Subject: Re: OSProcess - is process done?
Date: April 26, 2012 8:03:50 PM EDT
Sean,
Excellent, thanks for the feedback. As for #upToEnd, that's a tricky
question when you are reading from a pipe (or a socket). It is not
generally possible to ask the pipe whether more data is going to be
available on it. About the best you can do is ask it whether an end
of file condition was detected on the last read operation (there are
fancy ways to set up notification that a pipe was closed, but nothing
that I would want to try to implement in the OSPP plugin).
Based on that, I ended up doing #upToEndOfFile to mean "read all
available data, and keep trying until end of file is detected, then
answer the result" and #upToEnd to mean "read all currently available
data". In the case of a blocking stream (i.e. the end of the pipe
from which you are reading data), you want the underlying reads to
block (because that is the whole point of a blocking read), and
you want the reads to give you available data if the stream is set
to non-blocking. But there is no practical way to ask a blocking
pipe to give you all available data, because you cannot ask it how
much data it has available in advance of doing the read.
The combination of a pipe set to non-blocking mode, along with an
#upToEnd that reads whatever data is currently available, gives you
the behavior that you probably expect. But that implies that you
will poll for data (loop and keep reading until you get all the data)
or arrange for event notification to let you know when data is
available (this the AioPlugin, which notifies the image whenever
data becomes available for reading on a pipe).
There is a mechanism in OSProcess/CommandShell for converting a blocking
pipe into an event-driven buffered reader that handles these issues.
It is not well documented, but try this to see how it works:
p := PipeableOSProcess command: 'ls -l /usr/bin'.
p pipeFromOutput setBufferedReader.
p upToEndOfFile
This approach is used in CommandShell to provide the expected behavior
when the image is reading from a pipe connected to some external
process. And when pipes are connected end-to-end in a unix style
pipeline, they can be left in the normal blocking mode so that external
programs will block on reads from their stdin, which is the expected
behavior for normal programs in a unix command pipeline.
Dave