httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexei Kosut <ako...@organic.com>
Subject nph and lingering_close
Date Thu, 22 Aug 1996 22:12:19 GMT
Okay...

I've spent the last few hours trying to figure out why nph scripts don't
work with the lingering close code. It boils down to something like this:

When mod_cgi starts an nph script, it duplicates the client connection fd,
and passes it to the CGI script as stdout. Because there are two handles
to this fd, when bclose() closes its, it doesn't actually close the
socket because the CGI script still has one open. The connection stays
open until the CGI script exits. However, lingering_close() uses
shutdown(), which closes the socket right away, even though the CGI script
still has a handle open to it.

So... the fix? Well, a simple one is to simply make mod_cgi wait until the
CGI script finishes before passing control back to Apache. This way you
sidestep the problem entirely. Patch follows:

Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.17
diff -c -r1.17 mod_cgi.c
*** mod_cgi.c	1996/08/20 11:51:03	1.17
--- mod_cgi.c	1996/08/22 21:29:36
***************
*** 351,356 ****
--- 351,357 ----
  	(cgi_server_conf *)get_module_config(sconf, &cgi_module);
  
      struct cgi_child_stuff cld;
+     pid_t child_pid;
  
      if (r->method_number == M_OPTIONS) {
          /* 99 out of 100 CGI scripts, this is all they support */
***************
*** 389,401 ****
      cld.argv0 = argv0; cld.r = r; cld.nph = nph;
      cld.debug = conf->logname ? 1 : 0;
      
!     if (!spawn_child_err (r->connection->pool, cgi_child, (void *)&cld,
! 		      nph ? just_wait : kill_after_timeout,
  #ifdef __EMX__
! 		      &script_out, &script_in, &script_err)) {
  #else
!                       &script_out, nph ? NULL : &script_in,
!                       &script_err)) {
  #endif
          log_reason ("couldn't spawn child process", r->filename, r);
          return SERVER_ERROR;
--- 390,403 ----
      cld.argv0 = argv0; cld.r = r; cld.nph = nph;
      cld.debug = conf->logname ? 1 : 0;
      
!     if (!(child_pid =
! 	  spawn_child_err (r->connection->pool, cgi_child, (void *)&cld,
! 			   nph ? just_wait : kill_after_timeout,
  #ifdef __EMX__
! 			   &script_out, &script_in, &script_err))) {
  #else
! 			   &script_out, nph ? NULL : &script_in,
! 	    		   &script_err))) {
  #endif
          log_reason ("couldn't spawn child process", r->filename, r);
          return SERVER_ERROR;
***************
*** 491,503 ****
  	pfclose (r->connection->pool, script_err);
      }
  
- #ifdef __EMX__
      if (nph) {
          while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
              bputs(argsbuffer, r->connection->client);
          }
!     }    
  #endif
  
      return OK;			/* NOT r->status, even if it has changed. */
  }
--- 493,507 ----
  	pfclose (r->connection->pool, script_err);
      }
  
      if (nph) {
+ #ifdef __EMX__
          while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
              bputs(argsbuffer, r->connection->client);
          }
! #else
! 	waitpid(child_pid, (int*)0, 0);
  #endif
+     }    
  
      return OK;			/* NOT r->status, even if it has changed. */
  }


-- Alexei Kosut <akosut@organic.com>            The Apache HTTP Server 
   http://www.nueva.pvt.k12.ca.us/~akosut/      http://www.apache.org/


Mime
View raw message