httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nathan J Kurz <n...@tripod.tripod.com>
Subject Re: SIGPIPE on Solaris 2.5.1
Date Tue, 22 Apr 1997 05:34:13 GMT
> I spent the night trying to understand why we don't get a SIGPIPE
> on Solaris 2.5 after the user presses Stop on the client.  According
> to netstat, the socket is closing properly, but we just continue writing
> until the request times out (my patch is needed for the time out)
> because the server process never receives a SIGPIPE and the write
> never returns EPIPE.  As far as I can tell, Solaris is just broken
> in this regard.

I agree -- I think that Solaris is just broken here.  But I think that
EPIPE is always set.  I've walked through a number of times with gdb,
and it seems that for Solaris 2.5.1 write() will occasionally return
-1 and set errno to EPIPE without raising SIGPIPE.  But a second
write() always seems to work as expected.  

So a patch like this to the end of buff.c:bcwrite() seems to work:

#ifdef SOLARIS2
    nbyte = write(fb->fd, buf, nbyte);
    if (nbyte == -1 && errno == EPIPE) {
      /* valiantly try to raise a SIGPIPE to cover for a Solaris 2.5.1 bug */
      write(fb->fd, NULL, 0);
    }
    return nbyte;
#endif /* SOLARIS2 */

But this solution is so ugly that I don't think you'd want to do it.
Since the write does correctly return a -1, doerror() is called in
bwrite().  All subsequent calls to bwrite() return -1 without making a
write() attempt.  So the only real problem is the we have to keep
reading until the end of file, throwing away the output.

Except for CGI's.  I wonder if this bug might explain some of the
problems with CGI's not receiving SIGPIPE's when the client closes.

Seperately from this, I'm confused about the way send_long_fd handles
write errors.  Why keep trying to write after bwrite() returns an
error?  Should it be done only if errno is EAGAIN?

nate@tripod.com
http://www.tripod.com



Mime
View raw message