DIRECTORY BridgeComm, BridgeExec, IO, NetworkStream, Process, Rope ; BridgeCommImpl: CEDAR PROGRAM IMPORTS IO, NetworkStream, Process, Rope EXPORTS BridgeComm ~ { ROPE: TYPE ~ Rope.ROPE; NetworkStreamPair: TYPE ~ BridgeExec.NetworkStreamPair; Error: PUBLIC ERROR [msg: ROPE] ~ CODE; GetRopeToEOM: PUBLIC PROC [nsp: NetworkStreamPair] RETURNS [rope: ROPE ¬ NIL] ~ { rope ¬ IO.GetRope[nsp.in]; DO { state: NetworkStream.StreamState; [streamState~state] ¬ NetworkStream.GetStreamState[nsp.in, TRUE]; IF state = open OR state = remoteClosed THEN EXIT; } ENDLOOP; }; GetMsg: PUBLIC PROC [nsp: NetworkStreamPair] RETURNS [msg: CHAR, arg: ROPE] ~ { ENABLE { NetworkStream.Error -- [..., msg] -- => ERROR Error[msg]; IO.Error -- [..., stream] -- => ERROR Error[ Rope.Concat["I/O error", NetworkStream.GetIOErrorDetails[stream].msg ]]; IO.EndOfStream => ERROR Error["end of stream"]; }; msg ¬ IO.GetChar[nsp.in]; arg ¬ GetRopeToEOM[nsp]; }; PutMsg: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL] ~ { ENABLE { NetworkStream.Error -- [..., msg] -- => ERROR Error[msg]; NetworkStream.Timeout -- [..., msg] -- => ERROR Error["timeout"]; IO.Error -- [..., stream] -- => ERROR Error[ Rope.Concat["I/O error", NetworkStream.GetIOErrorDetails[stream].msg ]]; }; IO.PutChar[nsp.out, msg]; IO.PutRope[nsp.out, arg]; NetworkStream.SendEndOfMessage[nsp.out]; }; PutMsgWithReply: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL] RETURNS [ansMsg: CHAR, ansArg: ROPE] ~ { PutMsg[nsp, msg, arg]; NetworkStream.SendSoon[nsp.out, 0]; [ansMsg, ansArg] ¬ GetMsg[nsp]; }; PutMsgWithAck: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL] ~ { ansMsg: CHAR; ansArg: ROPE; PutMsg[nsp, msg, arg]; NetworkStream.SendSoon[nsp.out, 0]; [ansMsg, ansArg] ¬ GetMsg[nsp]; IF ansMsg # 'Y THEN ERROR Error[ IF ansMsg = 'N THEN ansArg ELSE NIL ]; }; closeRequestSST: NetworkStream.SubStreamType ¬ 254; closeReplySST: NetworkStream.SubStreamType ¬ 255; CloseConnectionWorker: PROC [nsp: NetworkStreamPair, action: BridgeComm.CloseHandshakeAction] ~ { SELECT action FROM initiate => IF nsp.out # NIL THEN { ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE; NetworkStream.SetTimeout[nsp.out, 2000]; NetworkStream.SetSubStreamType[nsp.out, closeRequestSST]; NetworkStream.SendSoon[nsp.out, 0]; }; ENDCASE; SELECT action FROM initiate => IF nsp.in # NIL THEN { ENABLE IO.Error, IO.EndOfStream, NetworkStream.Error, NetworkStream.Timeout => CONTINUE; reply: NetworkStream.SubStreamType; state: NetworkStream.StreamState; NetworkStream.SetTimeout[nsp.in, 2000]; DO IO.Reset[nsp.in]; [streamState~state, subStreamType~reply] ¬ NetworkStream.GetStreamState[nsp.in, TRUE]; IF state = remoteClosed THEN EXIT; IF reply = closeReplySST THEN EXIT; ENDLOOP; }; ENDCASE; IF nsp.in # NIL THEN { ENABLE IO.Error, IO.EndOfStream, NetworkStream.Error, NetworkStream.Timeout => CONTINUE; IO.Close[nsp.in, TRUE]; }; SELECT action FROM initiate, reply => IF nsp.out # NIL THEN { ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE; NetworkStream.SetTimeout[nsp.out, 2000]; NetworkStream.SetSubStreamType[nsp.out, closeReplySST]; NetworkStream.SendSoon[nsp.out, 0]; NetworkStream.WaitAck[nsp.out, 2000]; }; ENDCASE => NULL; IF nsp.out # NIL THEN { ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE; IO.Close[nsp.out, TRUE]; }; }; CloseConnection: PUBLIC PROC [nsp: NetworkStreamPair, action: BridgeComm.CloseHandshakeAction] ~ { TRUSTED { Process.Detach[ FORK CloseConnectionWorker[nsp, action] ]; }; }; }... T BridgeCommImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Demers, February 13, 1991 12:39 pm PST Peter B. Kessler February 25, 1988 12:04:29 pm PST Tim Diebert: August 30, 1989 5:57:32 am PDT Chauser, April 14, 1993 10:22 am PDT Read to EOM and return chars read as a rope. Clear the EndOfStream condition. Κγ–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ1™