<> <> <> <> DIRECTORY IO USING [STREAM], Pup USING [Address, Socket], Rope USING [ROPE]; PupStream: CEDAR DEFINITIONS = { <> <> <<>> <> <<>> <> <> <> <<>> <> <<>> <> MARK: TYPE = [0..100H); STREAM: TYPE = IO.STREAM; ROPE: TYPE = Rope.ROPE; Milliseconds: TYPE = INT; waitForever: Milliseconds = INT.LAST; <> Create: PROC [remote: Pup.Address, getTimeout, putTimeout: Milliseconds] RETURNS [STREAM]; <> <> <> <<>> CheckConnection: PROC [STREAM]; <> <> Abort: PROC [STREAM, ROPE]; <> <> Push: PROC [STREAM]; <> <> SendMark: PROC [STREAM, MARK]; -- Includes a Push ConsumeMark: PROC [STREAM] RETURNS [MARK]; -- Skip all input until the next MARK <> SendAttention: PROC [STREAM]; <> WaitAttention: PROC [STREAM]; <> <> <> <> <> <<>> <> <> <> <<>> <> <> <<>> <> < INT.LAST>> <> <<>> <> <> <<>> <> <> <<>> <> <> <> <<>> <> <> <> <> <<>> <> <> <<>> Timeout: SIGNAL; <> <> <> <> <> CloseReason: TYPE = { localClose, localAbort, remoteClose, noRouteToNetwork, transmissionTimeout, remoteReject}; StreamClosing: ERROR [why: CloseReason, text: Rope.ROPE]; <> <> Listener: TYPE = REF ListenerRep; ListenerRep: TYPE; FilterProc: TYPE = PROC [clientData: REF ANY, remote: Pup.Address] RETURNS [reject: ROPE _ NIL]; <<(reject=NIL) => Accept>> ListenerProc: TYPE = PROC [stream: STREAM, clientData: REF ANY, remote: Pup.Address]; CreateListener: PROC [ local: Pup.Socket, -- Must be WellKnown worker: ListenerProc, getTimeout, putTimeout: Milliseconds, clientData: REF ANY _ NIL, filter: FilterProc _ NIL, -- NIL => Accept all requests echoFilter: FilterProc _ NIL] -- NIL => Answer all echos RETURNS [Listener]; <> <> <> <<1) Checking for duplicates. >> <<2) Calling the clients filter. Returning any non-NIL value will reject the connection. >> <<3) Creating a stream with the specified timeouts.>> <<4) FORKing a new instance of worker to interact with the new stream.>> <<5) Detaching the new process.>> <> <> <> <<>> DestroyListener: PROC [Listener]; <> <> <> <<>> <> <<>> <> <<>> Sockets: TYPE = REF SocketsRep; SocketsRep: TYPE; AllocateSocket: PROC [remote: Pup.Address] RETURNS [Sockets]; <> <> LocalAddress: PROC [Sockets] RETURNS [Pup.Address]; RemoteAddress: PROC [Sockets] RETURNS [Pup.Address]; SocketsFromStream: PROC [STREAM] RETURNS [Sockets]; <> WaitForRendezvous: PROC [sockets: Sockets, getTimeout, putTimeout, waitTimeout: Milliseconds] RETURNS [STREAM]; <> ActivelyRendezvous: PROC [sockets: Sockets, getTimeout, putTimeout: Milliseconds] RETURNS [STREAM]; <> <> <<>> <> <<>> <> <> << him: Pup.Address;>> << Now use your back door to do ProcessB.him _ ProcessA.me;>> <> << Be sure to call WaitForRendezvous on ProcessA before trying to Create the stream on ProcessB>> << stream _ PupStream.Create[him, 1000, 1000];>> <<>> <> SocketNotWellKnown: ERROR; SocketsAlreadyUsed: ERROR; }.