[racket] error writing to stream port (Broken pipe; errno=32)

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Sep 12 18:34:22 EDT 2014

To make the program concrete, suppose we have "a.rkt" as

 #lang racket/base

 (define (epipe? x)
   (and
    (exn:fail:filesystem:errno? x) 
    (equal? '(32 . posix) (exn:fail:filesystem:errno-errno x))))
 (define (epipe-handler x)
   "ignore")

 (with-handlers ([epipe? epipe-handler])
  (let loop ()
    (displayln "hi")
    (loop)))

and then we run

 racket a.rkt | more

and then we hit "q" to exit `more`.

In that case, we will get

 error writing to stream port
  system error: Broken pipe; errno=32

The problem is that `epipe-handler` returns a string that becomes the
result of the whole `with-handlers`. When Racket attempts to print that
string, it fails (outside the `with-handlers`, of course). In other
words, the exception reports the failure to print "ignore", not a
failure from `(displayln "hi")`.


In this little example, changing `epipe-handler` to

 (define (epipe-handler x)
   (void))

avoids the problem, because a void result isn't printed. Another solution is

 (define (epipe-handler x)
   (exit 0))

to immediately exit, instead of returning a value.




At Fri, 12 Sep 2014 21:57:30 +0200, Wolfgang Hukriede wrote:
> Hi Matthias, nice to meet you! Yes, this was what I was looking for.
> 
> For the records:
> 
> (define (epipe? x)
>   (and
>    (exn:fail:filesystem:errno? x) 
>    (equal? '(32 . posix) (exn:fail:filesystem:errno-errno x))))
> 
> (define (epipe-handler x)
>   "ignore")
> 
> (with-handlers
>  ((epipe? epipe-handler))
>  transput...)
> 
> Many thanks!
> 
> Results are mixed though. Usage like 
> 
> $ mzscheme --no-init-file --load pipetest.scm | head
> 
> mostly works okay, but depending on how and how much is written to
> standard out and on the parameters to "head" failures reproducibly
> occur: in some situations the signal is not caught, yielding a "system
> error: Broken pipe; errno=32" message (versions 6.1 and 5.93 on
> freebsd, and 4.1 on generic linux, 6.1 precompiled racket on
> archlinux), or sometimes the pipe even just hangs (6.1 on freebsd).
> These were the combinations I tried.
> (On 4.1 exn:fail:filesystem was used instead of non-existing
> exn:fail:filesystem:errno.)
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.