Re: [Boa-devel] CGI scripts and SIGPIPE
Brought to you by:
jnelson
From: Yves R. <y.r...@in...> - 2005-01-21 14:50:42
|
On Mon, Jul 07, 2003 at 04:17:47PM +0100, Yves Rutschle wrote: > I ran into an interesting "behaviour" (that some insist on > calling a bug): one of our pages is generated by a rather > slow CGI script. If the browser interrupts the download (by > pressing "stop" or going to another page) the CGI > consistently remains, cluttering the system. > > After tracking things down, I think the problem lies in how > Boa handles the SIGPIPE: it's ignored. Then, Boa forks, > plumbs the child's stdout directly to the socket, and execs > the CGI. Fair enough, but later on when the browser forcibly > closes the socket, the CGI gets a SIGPIPE and... ignores it. > > I find a simple: > > diff -u -r1.1.1.1 signals.c > --- signals.c 28 Oct 2002 17:26:04 -0000 1.1.1.1 > +++ signals.c 7 Jul 2003 15:02:28 -0000 > @@ -78,8 +78,8 @@ > sa.sa_handler = sigint; > sigaction(SIGINT, &sa, NULL); > > - sa.sa_handler = SIG_IGN; > - sigaction(SIGPIPE, &sa, NULL); > + // sa.sa_handler = SIG_IGN; > + // sigaction(SIGPIPE, &sa, NULL); > > sa.sa_handler = sigchld; > sigaction(SIGCHLD, &sa, NULL); > > seems to correct the problem, but there might be other > problems I unleash by not handling SIGPIPE? A year and a half later, a problem finally arose: When you click through links faster than the server delivers the pages, the browser might do one of two things: - leave the socket be in the background (IE seems to do that) - close the socket (Firefox seems to do that). In the second case, boa ends up writing to a closed socket, gets a sigpipe. With my change, obviously it then dies. I'll now reset the sigpipe handler to its default after the fork() in cgi.c: diff -u -r1.2 cgi.c --- src/cgi.c 8 Jul 2003 11:13:11 -0000 1.2 +++ src/cgi.c 21 Jan 2005 14:40:56 -0000 @@ -24,6 +24,7 @@ /* $Id: cgi.c,v 1.83.2.3 2002/07/23 15:49:54 jnelson Exp $ */ #include "boa.h" +#include <signal.h> static char *env_gen_extra(const char *key, const char *value, int extra); @@ -451,6 +452,7 @@ _exit(1); } } + signal(SIGPIPE, SIG_DFL); /* Let SIGPIP kill CGI */ if (use_pipes) { close(pipes[0]); /* tie cgi's STDOUT to it's write end of pipe */ which fixes my original _and_ my new problem, I'll let you know in 2 years if other problems arise from that :-) Y. |