You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Roy T. Fielding" <fi...@kiwi.ics.uci.edu> on 1999/03/07 17:31:49 UTC
[PATCH] always ignore SIGPIPE
>I'd be interested in hearing if I have missed some easier solution to
>the problem and/or if there are plans to ignore SIGPIPE in Apache and
>in what version number that might happen.
This has been on my list of things to do for a long time, so here
is a patch to do it. Since this is a touchy change, I'll wait for
some votes before committing.
....Roy
Index: main/http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.424
diff -u -r1.424 http_main.c
--- http_main.c 1999/02/22 16:50:25 1.424
+++ http_main.c 1999/03/07 16:27:25
@@ -1021,10 +1021,9 @@
static APACHE_TLS int volatile alarm_pending = 0;
static void timeout(int sig)
-{ /* Also called on SIGPIPE */
+{
void *dirconf;
- signal(SIGPIPE, SIG_IGN); /* Block SIGPIPE */
if (alarms_blocked) {
alarm_pending = 1;
return;
@@ -1042,20 +1041,10 @@
else
dirconf = current_conn->server->lookup_defaults;
if (!current_conn->keptalive) {
- if (sig == SIGPIPE) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
- current_conn->server,
- "[client %s] stopped connection before %s completed",
- current_conn->remote_ip,
- timeout_name ? timeout_name : "request");
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
- current_conn->server,
- "[client %s] %s timed out",
- current_conn->remote_ip,
- timeout_name ? timeout_name : "request");
- }
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
+ current_conn->server, "[client %s] %s timed out",
+ current_conn->remote_ip,
+ timeout_name ? timeout_name : "request");
}
if (timeout_req) {
@@ -2757,6 +2746,11 @@
if (sigaction(SIGXFSZ, &sa, NULL) < 0)
ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGXFSZ)");
#endif
+#ifdef SIGPIPE
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGPIPE, &sa, NULL) < 0)
+ ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGPIPE)");
+#endif
/* we want to ignore HUPs and USR1 while we're busy processing one */
sigaddset(&sa.sa_mask, SIGHUP);
@@ -2796,6 +2790,10 @@
#ifdef SIGUSR1
signal(SIGUSR1, restart);
#endif /* SIGUSR1 */
+#ifdef SIGPIPE
+ signal(SIGPIPE, SIG_IGN);
+#endif /* SIGPIPE */
+
#endif
}
@@ -3578,8 +3576,7 @@
(void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL);
/*
- * Setup the jump buffers so that we can return here after
- * a signal or a timeout (yeah, I know, same thing).
+ * Setup the jump buffers so that we can return here after a timeout
*/
ap_setjmp(jmpbuffer);
#ifndef OS2
@@ -3587,7 +3584,6 @@
signal(SIGURG, timeout);
#endif
#endif
- signal(SIGPIPE, timeout);
signal(SIGALRM, alrm_handler);
#ifdef OS2
@@ -4907,8 +4903,7 @@
(void) ap_update_child_status(child_num, SERVER_READY, (request_rec *) NULL);
/*
- * Setup the jump buffers so that we can return here after
- * a signal or a timeout (yeah, I know, same thing).
+ * Setup the jump buffers so that we can return here after a timeout.
*/
#if defined(USE_LONGJMP)
setjmp(jmpbuffer);
@@ -4927,16 +4922,14 @@
* (Re)initialize this child to a pre-connection state.
*/
- ap_set_callback_and_alarm(NULL, 0); /* Cancel any outstanding alarms. */
- timeout_req = NULL; /* No request in progress */
+ ap_set_callback_and_alarm(NULL, 0); /* Cancel any outstanding alarms */
+ timeout_req = NULL; /* No request in progress */
current_conn = NULL;
-#ifdef SIGPIPE
- signal(SIGPIPE, timeout);
-#endif
ap_clear_pool(ptrans);
- (void) ap_update_child_status(child_num, SERVER_READY, (request_rec *) NULL);
+ (void) ap_update_child_status(child_num, SERVER_READY,
+ (request_rec *) NULL);
/* Get job from the job list. This will block until a job is ready.
* If -1 is returned then the main thread wants us to exit.
Index: modules/proxy/proxy_http.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v
retrieving revision 1.62
diff -u -r1.62 proxy_http.c
--- proxy_http.c 1999/02/07 20:48:32 1.62
+++ proxy_http.c 1999/03/07 16:27:26
@@ -352,7 +352,7 @@
}
ap_bputs(CRLF, f);
-/* send the request data, if any. N.B. should we trap SIGPIPE ? */
+/* send the request data, if any. */
if (ap_should_client_block(r)) {
while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0)
Index: modules/standard/mod_cgi.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_cgi.c,v
retrieving revision 1.88
diff -u -r1.88 mod_cgi.c
--- mod_cgi.c 1999/01/01 19:05:08 1.88
+++ mod_cgi.c 1999/03/07 16:27:26
@@ -440,16 +440,10 @@
}
/* Transfer any put/post args, CERN style...
- * Note that if a buggy script fails to read everything we throw
- * at it, or a buggy client sends too much, we get a SIGPIPE, so
- * we have to ignore SIGPIPE while doing this. CERN does the same
- * (and in fact, they pretty nearly guarantee themselves a SIGPIPE
- * on every invocation by chasing the real client data with a
- * spurious newline).
+ * Note that we already ignore SIGPIPE in the core server.
*/
if (ap_should_client_block(r)) {
- void (*handler) (int);
int dbsize, len_read;
if (conf->logname) {
@@ -458,9 +452,6 @@
}
ap_hard_timeout("copy script args", r);
-#ifdef SIGPIPE
- handler = signal(SIGPIPE, SIG_IGN);
-#endif
while ((len_read =
ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN)) > 0) {
@@ -485,7 +476,6 @@
}
ap_bflush(script_out);
- signal(SIGPIPE, handler);
ap_kill_timeout(r);
}
Re: [PATCH] always ignore SIGPIPE
Posted by "Frank D. Cringle" <fd...@cliwe.ping.de>.
"Roy T. Fielding" <fi...@kiwi.ics.uci.edu> writes:
> >I'd be interested in hearing if I have missed some easier solution to
> >the problem and/or if there are plans to ignore SIGPIPE in Apache and
> >in what version number that might happen.
>
> This has been on my list of things to do for a long time, so here
> is a patch to do it. Since this is a touchy change, I'll wait for
> some votes before committing.
I tried out this patch with a mod_perl script that produces output
slowly, so that I can abort the connection before it completes.
r->connection->aborted did not get set and the script continued to
run, oblivious of the fact that its output was going nowhere.
Most callers of ap_bwrite() in http_protocol.c check that the write
was successful and set r->connection->aborted if not. mod_perl's
writes go via ap_rwrite(), and that routine does not check the
return value from ap_bwrite(). It does pass it up to the caller, but
mod_perl does not does not make the information available as a
success/failure return value to callers of its Apache::print method.
I would suggest that r->connection->aborted should be set if the
ap_bwrite() call in ap_rwrite() fails. Also, Apache::print should
return 1/0 instead of undef and mod_perl should provide an option to
automatically kill the script if a print fails (further discussion of
these latter 2 points on the mod_perl list).
--
Frank Cringle, fdc@cliwe.ping.de
voice: (+49 2304) 467101; fax: 943357
Re: [PATCH] always ignore SIGPIPE
Posted by Dean Gaudet <dg...@arctic.org>.
On Sun, 7 Mar 1999, Roy T. Fielding wrote:
> >I'd be interested in hearing if I have missed some easier solution to
> >the problem and/or if there are plans to ignore SIGPIPE in Apache and
> >in what version number that might happen.
>
> This has been on my list of things to do for a long time, so here
> is a patch to do it. Since this is a touchy change, I'll wait for
> some votes before committing.
+1 on concept -- it's been something I was thinking about too.
Dean