httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roy T. Fielding" <field...@kiwi.ics.uci.edu>
Subject [PATCH] always ignore SIGPIPE
Date Sun, 07 Mar 1999 16:31:49 GMT
>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);
     }

Mime
View raw message