Ports input to Processes

Jens Petersen petersen@redhat.com
14 Apr 2002 01:14:21 +0900


Hi Manuel,

Trying again now with ghc-5.02.3:

"Manuel M. T. Chakravarty" <chak@cse.unsw.edu.au> writes:

> Jens Petersen <juhp@01.246.ne.jp> wrote,
> 
> >         http://www.cse.unsw.edu.au/~chak/haskell/ports/
> > 
> > It compiles fine under ghc-5.02.2, and using the BufferMode
> > patch included at the end output seems to be ok, 
> 
> Why LineBuffering?  Doesn't really change anything for me
> (same GHC version).

You're right, I think.

> > but input
> > of more than 2048 bytes doesn't seem to be being handled
> > reliably.
> [..]
> > mostly gives no output, but occasionally I see
> > 
> >         Warning: Ports.listenToPort: Attempted to listen to a closed port!
> > 
> > Needs some debugging I guess. :)
> 
> I guess, it needs more documentation.  Your test program is
> wrong in two places.
> 
> The function `listenToPort' starts to listens at the given
> port exactly when `listenToPort' is executed; ie, any data
> that goes over the port earlier will not be received in the
> stream that this call to `listenToPort' returns.  
> 
> You wrote
> 
> >        outpt <- newPort ' '
> >        errpt <- newPort ' '
> >        let p = proc cmd args
> >        p inpt outpt errpt
> >        putStrLn "output:"
> >        out <- listenToPort outpt
> 
> As the processes `cmd' is fork()ed in a separate thread, it
> may already have finshed its business until you get to
> `listenToPort outpt', which means you have missed all the
> data.  For similar reasons

Ok.

> >        errclosed <- isClosedPort errpt
> >        unless errclosed $
> > 	 do
> > 	 err <- listenToPort errpt
> 
> isn't recommended.  

Fair enough.

> I changed your program to what I have appended.  It then
> works for me for the
> 
>         % cat 4096 | test-processes cat
> 
> test...except that I sometimes get a "Broken Pipe".  So, I
> guess, I have to do some debugging after all (plus improve
> the documentation).

With your program (just modified to output the length of the
output string instead of the output itself), for small
amounts of input (ie <= 4KiB), on the first invocation I see:

% cat small-file | ./ports cat  
output:
0
error:
cat: -: Resource temporarily unavailable
test finished

and then subsequent invocation perform as expected:

% cat small-file | ./ports cat 
output:
340
error:
test finished

For input larger than 4KiB the program never gives any
output for me, and always seems to terminate prematurely:

% cat large-file | ./ports cat 
output:
%

> PS: I'll add your program to the ports/tests/ directory if
>     you don't mind.

Sure, please do.

Jens