<<>> <> <> <> DIRECTORY BasicTime, Commander, IO, NetworkStream, Process, SimpleFeedback; RoundTripServer: CEDAR PROGRAM IMPORTS BasicTime, Commander, IO, NetworkStream, Process, SimpleFeedback = BEGIN Time: TYPE ~ RECORD [s, us: INT]; unixOrg: BasicTime.GMT ~ BasicTime.Pack[[year: 1970, month: January, day: 1, hour: 0, minute: 0, second: 0, zone: 0, dst: no]]; soon: CARD ¬ 0; l: NetworkStream.Listener ¬ NIL; SetSoon: Commander.CommandProc ~ { in: IO.STREAM ~ IO.RIS[cmd.commandLine]; soon ¬ in.GetCard[]; RETURN [$Success, IO.PutFR1["soon = %g", [cardinal[soon]] ]]}; Stopit: Commander.CommandProc ~ { IF l#NIL THEN { NetworkStream.DestroyListener[l !NetworkStream.Error => CONTINUE]; l ¬ NIL; Process.PauseMsec[5000]}; RETURN}; Restart: Commander.CommandProc ~ { IF l#NIL THEN { NetworkStream.DestroyListener[l !NetworkStream.Error => CONTINUE]; l ¬ NIL; Process.PauseMsec[5000]}; IF MakeListener[] THEN RETURN [$Success, "Server re-made"] ELSE RETURN [$Failure, "Something went wrong"]}; MakeListener: PROC RETURNS [success: BOOL ¬ TRUE] ~ { l ¬ NetworkStream.CreateListener[ protocolFamily: $ARPA, local: ":58801", transportClass: $basicStream, listenerWorkerProc: Work !NetworkStream.Error => { SimpleFeedback.PutFL[$RoundTripServer, oneLiner, $Error, "NetworkStream.Error[LIST[%g, ..], %g] creating RoundTripServer listener.", LIST[[atom[codes.first]], [rope[msg]] ]]; success ¬ FALSE; CONTINUE} ]; RETURN}; Work: PROC [listener: NetworkStream.Listener, in, out: IO.STREAM] ~ { start, mid: Time; GetNow: PROC RETURNS [Time] ~ { egmt: BasicTime.ExtendedGMT ~ BasicTime.ExtendedNow[]; RETURN [[BasicTime.Period[from: unixOrg, to: egmt.gmt], egmt.usecs]]}; GetTime: PROC RETURNS [Time] ~ { s: CARD ~ GetCard[]; us: CARD ~ GetCard[]; RETURN [[s, us]]}; GetCard: PROC RETURNS [CARD] ~ { hi: CARDINAL ~ GetShort[]; RETURN [hi*10000H + GetShort[]]}; GetShort: PROC RETURNS [CARDINAL] ~ { hi: BYTE ~ in.GetChar[].ORD; RETURN [hi*100H + in.GetChar[].ORD]}; PutCard: PROC [c: CARD] ~ {PutShort[c/10000H]; PutShort[c MOD 10000H]}; PutShort: PROC [c: CARDINAL] ~ { out.PutChar[VAL[c/100H]]; out.PutChar[VAL[c MOD 100H]]}; DO ENABLE IO.Error, IO.EndOfStream => EXIT; start ¬ GetTime[]; mid ¬ GetNow[]; PutCard[start.s]; PutCard[start.us]; PutCard[mid.s]; PutCard[mid.us]; NetworkStream.SendSoon[out, soon]; ENDLOOP; in.Close[!IO.Error => CONTINUE]; out.Close[!IO.Error => CONTINUE]; RETURN}; Start: PROC ~ { [] ¬ MakeListener[]; Commander.Register["RoundTripSetSoon", SetSoon, ""]; Commander.Register["RoundTripStop", Stopit, "kills server"]; Commander.Register["RoundTripRestart", Restart, "(re-)creates server"]; }; Start[]; END.