A Pipe.T
, or pipe, is a file handle that provides access to one
endpoint of a unidirectional channel that is typically used to
communicate between a parent and a child process or two sibling
processes. (See Process.Create
.)
INTERFACEPipe ; IMPORT File, OSError; TYPE T <: File.T; VAR (*CONST*) FileType: File.Type;
Equal to {\tt Atom.FromText("Pipe").}
PROCEDURE Open(VAR (*OUT*) hr, hw: T) RAISES {OSError.E};
Create a new channel allowing bytes written tohw
to be read fromhr
.
END Pipe.Like every
File.T
, a pipe h
has the components
type(h) an atom, equal to FileType readable(h) a boolean writable(h) a booleanExactly one of
readable(h)
and writable(h)
is true (until the
pipe is closed).
A pipe h
also has the component
channel(h) a channelIf there are pipes
hw
and hr
with channel(hw) = channel(hr)
,
writable(hw)
, and readable(hr)
, then a process holding hw
can
send information to a process holding hr
.
A channel c
has the components
seq(c) a sequence of bytes w(c) a non-negative integer, the index of the next byte to write r(c) a non-negative integer, the index of the next byte to read nw(c) a non-negative integer, the number of pipes writing c nr(c) a non-negative integer, the number of pipes reading cIt is possible (but not very useful) for a channel to have values of
nw(c)
or nr(c)
other than zero or one (see Process.Create
).
Open
creates a channel c
with
w(c) = r(c) = 0 nw(c) = nr(c) = 1and two pipes
hr
and hw
with
type(hr) = type(hw) = FileType readable(hr) = writable(hw) = TRUE writable(hr) = readable(hw) = FALSE channel(hr) = channel(hw) = c
The meaning of the call
h.read(b, mayBlock)is given by the specification of
File.T.read
together with these
definitions, where c = channel(h)
:
src(h) = seq(c) srcCur(h) = r(c) srcEof(h) = (nw(c) = 0)Note that end-of-file is not reported until after the last pipe that can write on the channel is closed; subsequent reads are legal but always report end-of-file.
The meaning of the call
h.write(b)is given by the specification of
File.T.write
together with these
definitions, where c = channel(h)
:
snk(h) = seq(c) snkCur(h) = w(c)In some implementations, a channel has a bounded buffer, so
write
may have to block. If nr(channel(h)) = 0
, that is, no pipe can
read h
's channel, write
raises OSError.E
.
The call
h.status(stat)assigns
FileType
to stat.type
. Its effect on
stat.modificationTime
and stat.size
is undefined.
The call
h.close()is equivalent to
IF readable(h) THEN DEC(nr(channel(h))) ELSE DEC(nw(channel(h))) END; readable(h) := FALSE; writable(h) := FALSEThe channel connecting a pair of pipes is necessarily monitored, since the purpose of the channel is to allow asynchronous communication via the pipes. Nevertheless, an individual pipe should be treated as unmonitored, thus avoiding the question of the unit of atomicity for reads and writes.