httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jim Jagielski <...@jaguNET.com>
Subject Re: [PATCH] nph killer, cgi buffering
Date Sun, 20 Jul 1997 01:29:21 GMT
Isn't this basically sameer's code that was committed and then
pulled?

Dean Gaudet wrote:
> 
> This patch:
> 
> - provides BUFF * interfaces to the various things cgi needs, in a way
>   that avoids mucho code duplication
> 
> - adds bnonblock() to set a BUFF to non-blocking mode, and bfileno() to
>   get an fd for calling select() on.
> 
> - provides send_fb/send_fb_length which do non-blocking reads, and
>   whenever a read would block they bflush the client before blocking.
> 
> - eliminates the special case "nph-" for CGIs.  (nph doesn't work with
>   HTTP/1.1 or SSL)
> 
> - works on simple .cgis, needs testing via mod_include, needs more eyes
>   to look at it.  Needs testing on NT (needs porting??).
> 
> Dean
> 
> Index: alloc.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/alloc.c,v
> retrieving revision 1.40
> diff -u -r1.40 alloc.c
> --- alloc.c	1997/07/15 21:39:50	1.40
> +++ alloc.c	1997/07/20 00:56:14
> @@ -1064,9 +1064,16 @@
>  #define enc_pipe(fds) pipe(fds)
>  #endif /* WIN32 */
>  
> -API_EXPORT(int) spawn_child_err (pool *p, int (*func)(void *), void *data,
> +/* for fdopen, to get binary mode */
> +#if defined (__EMX__) || defined (WIN32)
> +#define BINMODE	"b"
> +#else
> +#define BINMODE
> +#endif
> +
> +static int spawn_child_err_core (pool *p, int (*func)(void *), void *data,
>  		     enum kill_conditions kill_how,
> -		     FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
> +		     int *pipe_in, int *pipe_out, int *pipe_err)
>  {
>    int pid;
>    int in_fds[2];
> @@ -1074,13 +1081,7 @@
>    int err_fds[2];
>    int save_errno;
>  
> -  block_alarms();
> -  
> -  if (pipe_in && enc_pipe (in_fds) < 0)
> -  {
> -      save_errno = errno;
> -      unblock_alarms();
> -      errno = save_errno;
> +  if (pipe_in && enc_pipe (in_fds) < 0) {
>        return 0;
>    }
>    
> @@ -1089,7 +1090,6 @@
>      if (pipe_in) {
>        close (in_fds[0]); close (in_fds[1]);
>      }
> -    unblock_alarms();
>      errno = save_errno;
>      return 0;
>    }
> @@ -1102,7 +1102,6 @@
>      if (pipe_out) {
>        close (out_fds[0]); close (out_fds[1]);
>      }
> -    unblock_alarms();
>      errno = save_errno;
>      return 0;
>    }
> @@ -1158,23 +1157,14 @@
>        if(pid)
>        {
>            note_subprocess(p, pid, kill_how);
> -          if(pipe_in)
> -          {
> -              *pipe_in = fdopen(in_fds[1], "wb");
> -              if(*pipe_in)
> -                  note_cleanups_for_file(p, *pipe_in);
> +          if(pipe_in) {
> +	      *pipe_in = in_fds[1];
>            }
> -          if(pipe_out)
> -          {
> -              *pipe_out = fdopen(out_fds[0], "rb");
> -              if(*pipe_out)
> -                  note_cleanups_for_file(p, *pipe_out);
> +          if(pipe_out) {
> +	      *pipe_out = out_fds[0];
>            }
> -          if(pipe_err)
> -          {
> -              *pipe_err = fdopen(err_fds[0], "rb");
> -              if(*pipe_err)
> -                  note_cleanups_for_file(p, *pipe_err);
> +          if(pipe_err) {
> +              *pipe_err = err_fds[0];
>            }
>        }
>        SetThreadPriority(thread_handle, old_priority);
> @@ -1198,7 +1188,6 @@
>      if (pipe_err) {
>        close (err_fds[0]); close (err_fds[1]);
>      }
> -    unblock_alarms();
>      errno = save_errno;
>      return 0;
>    }
> @@ -1237,43 +1226,106 @@
>    
>    if (pipe_out) {
>      close (out_fds[1]);
> -#ifdef __EMX__
> -    /* Need binary mode set for OS/2. */
> -    *pipe_out = fdopen (out_fds[0], "rb");
> -#else
> -    *pipe_out = fdopen (out_fds[0], "r");
> -#endif  
> -  
> -    if (*pipe_out) note_cleanups_for_file (p, *pipe_out);
> +    *pipe_out = out_fds[0];
>    }
>  
>    if (pipe_in) {
>      close (in_fds[0]);
> -#ifdef __EMX__
> -    /* Need binary mode set for OS/2 */
> -    *pipe_in = fdopen (in_fds[1], "wb");
> -#else
> -    *pipe_in = fdopen (in_fds[1], "w");
> -#endif
> -    
> -    if (*pipe_in) note_cleanups_for_file (p, *pipe_in);
> +    *pipe_in = in_fds[1];
>    }
>  
>    if (pipe_err) {
>      close (err_fds[1]);
> -#ifdef __EMX__
> -    /* Need binary mode set for OS/2. */
> -    *pipe_err = fdopen (err_fds[0], "rb");
> -#else
> -    *pipe_err = fdopen (err_fds[0], "r");
> -#endif
> -  
> -    if (*pipe_err) note_cleanups_for_file (p, *pipe_err);
> +    *pipe_err = err_fds[0];
>    }
>  #endif /* WIN32 */
>  
> -  unblock_alarms();
>    return pid;
> +}
> +
> +
> +API_EXPORT(int) spawn_child_err (pool *p, int (*func)(void *), void *data,
> +		     enum kill_conditions kill_how,
> +		     FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
> +{
> +    int fd_in, fd_out, fd_err;
> +    int pid, save_errno;
> +
> +    block_alarms();
> +
> +    pid = spawn_child_err_core (p, func, data, kill_how,
> +	    pipe_in ? &fd_in : NULL,
> +	    pipe_out ? &fd_out : NULL,
> +	    pipe_err ? &fd_err : NULL );
> +
> +    if (pid == 0) {
> +	save_errno = errno;
> +	unblock_alarms();
> +	errno = save_errno;
> +	return 0;
> +    }
> +
> +    if (pipe_out) {
> +	*pipe_out = fdopen (fd_out, "r" BINMODE);
> +	if (*pipe_out) note_cleanups_for_file (p, *pipe_out);
> +	else close (fd_out);
> +    }
> +
> +    if (pipe_in) {
> +	*pipe_in = fdopen (fd_in, "w" BINMODE);
> +	if (*pipe_in) note_cleanups_for_file (p, *pipe_in);
> +	else close (fd_in);
> +    }
> +
> +    if (pipe_err) {
> +	*pipe_err = fdopen (fd_err, "r" BINMODE);
> +	if (*pipe_err) note_cleanups_for_file (p, *pipe_err);
> +	else close (fd_err);
> +    }
> +
> +    unblock_alarms();
> +    return pid;
> +}
> +
> +
> +API_EXPORT(int) spawn_child_err_buff (pool *p, int (*func)(void *), void *data,
> +			  enum kill_conditions kill_how,
> +			  BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err)
> +{
> +    int fd_in, fd_out, fd_err;
> +    int pid, save_errno;
> +
> +    block_alarms();
> +
> +    pid = spawn_child_err_core (p, func, data, kill_how,
> +	    pipe_in ? &fd_in : NULL,
> +	    pipe_out ? &fd_out : NULL,
> +	    pipe_err ? &fd_err : NULL );
> +
> +    if (pid == 0) {
> +	save_errno = errno;
> +	unblock_alarms();
> +	errno = save_errno;
> +	return 0;
> +    }
> +  
> +    if (pipe_out) {
> +	*pipe_out = bcreate(p, B_RD);
> +	bpushfd(*pipe_out, fd_out, fd_out);
> +    }
> +
> +    if (pipe_in) {
> +	*pipe_in = bcreate(p, B_WR);
> +	bpushfd(*pipe_in, fd_in, fd_in);
> +    }
> +
> +    if (pipe_err) {
> +	*pipe_err = bcreate(p, B_RD);
> +	bpushfd(*pipe_err, fd_err, fd_err);
> +    }
> +
> +    unblock_alarms();
> +    return pid;
>  }
>  
>  static void free_proc_chain (struct process_chain *procs)
> Index: buff.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/buff.c,v
> retrieving revision 1.37
> diff -u -r1.37 buff.c
> --- buff.c	1997/07/15 21:39:50	1.37
> +++ buff.c	1997/07/20 00:56:16
> @@ -415,18 +415,38 @@
>  {
>      if (value) {
>  	fb->flags |= flag;
> -	if( flag & B_CHUNK ) {
> +	if (flag & B_CHUNK) {
>  	    start_chunk(fb);
>  	}
>      } else {
>  	fb->flags &= ~flag;
> -	if( flag & B_CHUNK ) {
> +	if (flag & B_CHUNK) {
>  	    end_chunk(fb);
>  	}
>      }
>      return value;
>  }
>  
> +
> +API_EXPORT(int) bnonblock(BUFF *fb, int direction)
> +{
> +    int fd;
> +
> +    fd = ( direction == B_RD ) ? fb->fd_in : fb->fd;
> +#if defined(O_NONBLOCK)
> +    return fcntl (fd, F_SETFL, O_NONBLOCK);
> +#elif defined(F_NDELAY)
> +    return fcntl (fd, F_SETFL, F_NDELAY);
> +#else
> +    return 0;
> +#endif
> +}
> +
> +API_EXPORT(int) bfileno(BUFF *fb, int direction)
> +{
> +    return (direction == B_RD) ? fb->fd_in : fb->fd;
> +}
> +
>  /*
>   * This is called instead of read() everywhere in here.  It implements
>   * the B_SAFEREAD functionality -- which is to force a flush() if a read()
> @@ -521,10 +541,18 @@
>      if (fb->flags & B_RDERR) return -1;
>      if (nbyte == 0) return 0;
>  
> -    if (!(fb->flags & B_RD))
> -    {
> -/* Unbuffered reading */
> +    if (!(fb->flags & B_RD)) {
> +	/* Unbuffered reading.  First check if there was something in the
> +	 * buffer from before we went unbuffered. */
> +	if (fb->incnt) {
> +	    i = (fb->incnt > nbyte) ? nbyte : fb->incnt;
> +	    memcpy (buf, fb->inptr, i);
> +	    fb->incnt -= i;
> +	    fb->inptr += i;
> +	    return i;
> +	}
>  	i = saferead( fb, buf, nbyte );
> +	if (i == 0) fb->flags |= B_EOF;
>  	if (i == -1 && errno != EAGAIN) doerror(fb, B_RD);
>  	return i;
>      }
> Index: buff.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/buff.h,v
> retrieving revision 1.21
> diff -u -r1.21 buff.h
> --- buff.h	1997/07/19 22:34:05	1.21
> +++ buff.h	1997/07/20 00:56:17
> @@ -158,3 +158,12 @@
>  #define bputc(c, fb) ((((fb)->flags & (B_EOUT|B_WRERR|B_WR)) != B_WR || \
>  		     (fb)->outcnt == (fb)->bufsiz) ? bflsbuf(c, (fb)) : \
>  		     ((fb)->outbase[(fb)->outcnt++] = (c), 0))
> +
> +API_EXPORT(int) spawn_child_err_buff (pool *, int (*)(void *), void *,
> +           	  enum kill_conditions, BUFF **pipe_in, BUFF **pipe_out,
> +                  BUFF **pipe_err);
> +
> +/* enable non-blocking operations */
> +API_EXPORT(int) bnonblock(BUFF *fb, int direction);
> +/* and get an fd to select() on */
> +API_EXPORT(int) bfileno(BUFF *fb, int direction);
> Index: http_protocol.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/http_protocol.c,v
> retrieving revision 1.143
> diff -u -r1.143 http_protocol.c
> --- http_protocol.c	1997/07/19 20:27:52	1.143
> +++ http_protocol.c	1997/07/20 00:56:22
> @@ -1626,6 +1626,85 @@
>      return total_bytes_sent;
>  }
>  
> +/*
> + * Send the body of a response to the client.
> + */
> +API_EXPORT(long) send_fb(BUFF *fb, request_rec *r) {
> +    return send_fb_length(fb, r, -1);
> +}
> +
> +API_EXPORT(long) send_fb_length(BUFF *fb, request_rec *r, long length)
> +{
> +    char buf[IOBUFSIZE];
> +    long total_bytes_sent = 0;
> +    register int n, w, o, len, fd;
> +    fd_set fds;
> +    
> +    if (length == 0) return 0;
> +
> +    /* Make fb unbuffered and non-blocking */
> +    bsetflag (fb, B_RD, 0);
> +    bnonblock (fb, B_RD);
> +    fd = bfileno (fb, B_RD);
> +
> +    soft_timeout("send body", r);
> +
> +    while (!r->connection->aborted) {
> +	if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
> +	    len = length - total_bytes_sent;
> +	else len = IOBUFSIZE;
> +
> +	do {
> +	    n = bread (fb, buf, len);
> +	    if (n >= 0) break;
> +	    if (n < 0 && errno != EAGAIN) break;
> +	    /* we need to block, so flush the output first */
> +	    bflush (r->connection->client);
> +	    FD_ZERO (&fds);
> +	    FD_SET (fd, &fds);
> +	    /* we don't care what select says, we might as well loop back
> +	     * around and try another read
> +	     */
> +	    ap_select (fd+1, &fds, NULL, NULL, NULL);
> +	} while (!r->connection->aborted);
> +
> +	if (n < 1 || r->connection->aborted) {
> +	    break;
> +	}
> +
> +        o=0;
> +	total_bytes_sent += n;
> +
> +        while (n && !r->connection->aborted) {
> +            w = bwrite(r->connection->client, &buf[o], n);
> +            if (w > 0) {
> +                reset_timeout(r); /* reset timeout after successful write */
> +                n-=w;
> +                o+=w;
> +            }
> +            else if (w < 0) {
> +                if (r->connection->aborted)
> +                    break;
> +                else if (errno == EAGAIN)
> +                    continue;
> +                else {
> +                    log_unixerr("send body lost connection to",
> +                                get_remote_host(r->connection,
> +                                    r->per_dir_config, REMOTE_NAME),
> +                                NULL, r->server);
> +                    bsetflag(r->connection->client, B_EOUT, 1);
> +                    r->connection->aborted = 1;
> +                    break;
> +                }
> +            }
> +        }
> +    }
> +
> +    kill_timeout(r);
> +    SET_BYTES_SENT(r);
> +    return total_bytes_sent;
> +}
> +
>  API_EXPORT(int) rputc (int c, request_rec *r)
>  {
>      if (r->connection->aborted) return EOF;
> Index: http_protocol.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/http_protocol.h,v
> retrieving revision 1.24
> diff -u -r1.24 http_protocol.h
> --- http_protocol.h	1997/07/19 20:27:52	1.24
> +++ http_protocol.h	1997/07/20 00:56:23
> @@ -110,6 +110,9 @@
>  
>  API_EXPORT(long) send_fd(FILE *f, request_rec *r);
>  API_EXPORT(long) send_fd_length(FILE *f, request_rec *r, long length);
> +
> +API_EXPORT(long) send_fb(BUFF *f, request_rec *r);
> +API_EXPORT(long) send_fb_length(BUFF *f, request_rec *r, long length);
>       
>  /* Hmmm... could macrofy these for now, and maybe forever, though the
>   * definitions of the macros would get a whole lot hairier.
> Index: mod_cgi.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
> retrieving revision 1.49
> diff -u -r1.49 mod_cgi.c
> --- mod_cgi.c	1997/07/17 22:27:34	1.49
> +++ mod_cgi.c	1997/07/20 00:56:24
> @@ -183,7 +183,7 @@
>  }
>  
>  static int log_script(request_rec *r, cgi_server_conf *conf, int ret,
> -	       char *dbuf, char *sbuf, FILE *script_in, FILE *script_err)
> +		    char *dbuf, char *sbuf, BUFF *script_in, BUFF *script_err)
>  {
>      table *hdrs_arr = r->headers_in;
>      table_entry *hdrs = (table_entry *)hdrs_arr->elts;
> @@ -197,9 +197,9 @@
>  	((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname),
>  		     "a")) == NULL)) {
>        /* Soak up script output */
> -      while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in))
> +      while (bgets(argsbuffer, HUGE_STRING_LEN, script_in))
>  	continue;
> -      while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err))
> +      while (bgets(argsbuffer, HUGE_STRING_LEN, script_err))
>  	continue;
>        return ret;
>      }
> @@ -207,7 +207,7 @@
>      /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
>      fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri,
>  	    r->args ? "?" : "", r->args ? r->args : "", r->protocol);
> -    /* "%% 500 /usr/local/etc/httpd/cgi-bin */
> +    /* "%% 500 /usr/local/etc/httpd/cgi-bin" */
>      fprintf(f, "%%%% %d %s\n", ret, r->filename);
>  
>      fputs("%request\n", f);
> @@ -216,7 +216,7 @@
>        fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
>      }
>      if ((r->method_number == M_POST || r->method_number == M_PUT)
> -	&& dbuf && *dbuf) {
> +	&& *dbuf) {
>        fprintf(f, "\n%s\n", dbuf);
>      }
>  
> @@ -233,27 +233,27 @@
>        fprintf(f, "%s\n", sbuf);
>  
>      *argsbuffer = '\0';
> -    fgets(argsbuffer, HUGE_STRING_LEN-1, script_in);
> +    bgets(argsbuffer, HUGE_STRING_LEN, script_in);
>      if (*argsbuffer) {
>        fputs("%stdout\n", f);
>        fputs(argsbuffer, f);
> -      while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in))
> +      while (bgets(argsbuffer, HUGE_STRING_LEN, script_in))
>  	fputs(argsbuffer, f);
>        fputs("\n", f);
>      }
>  
>      *argsbuffer = '\0';
> -    fgets(argsbuffer, HUGE_STRING_LEN-1, script_err);
> +    bgets(argsbuffer, HUGE_STRING_LEN, script_err);
>      if (*argsbuffer) {
>        fputs("%stderr\n", f);
>        fputs(argsbuffer, f);
> -      while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err))
> +      while (bgets(argsbuffer, HUGE_STRING_LEN, script_err))
>  	fputs(argsbuffer, f);
>        fputs("\n", f);
>      }
>  
> -    pfclose(r->main ? r->main->pool : r->pool, script_in);
> -    pfclose(r->main ? r->main->pool : r->pool, script_err);
> +    bclose(script_in);
> +    bclose(script_err);
>  
>      pfclose(r->pool, f);
>      return ret;
> @@ -277,7 +277,6 @@
>      struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff;
>      request_rec *r = cld->r;
>      char *argv0 = cld->argv0;
> -    int nph = cld->nph;
>      int child_pid;
>  
>  #ifdef DEBUG_CGI    
> @@ -312,10 +311,6 @@
>      if (!cld->debug)
>        error_log2stderr (r->server);
>  
> -#if !defined(__EMX__) && !defined(WIN32)
> -    if (nph) client_to_stdout (r->connection);
> -#endif    
> -
>      /* Transumute outselves into the script.
>       * NB only ISINDEX scripts get decoded arguments.
>       */
> @@ -352,7 +347,7 @@
>  {
>      int retval, nph, dbpos = 0;
>      char *argv0, *dbuf = NULL;
> -    FILE *script_out, *script_in, *script_err;
> +    BUFF *script_out, *script_in, *script_err;
>      char argsbuffer[HUGE_STRING_LEN];
>      int is_included = !strcmp (r->protocol, "INCLUDED");
>      void *sconf = r->server->module_config;
> @@ -421,15 +416,10 @@
>  	   * waiting for free_proc_chain to cleanup in the middle of an
>  	   * SSI request -djg
>  	   */
> -	  spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child,
> -			    (void *)&cld,
> -			   nph ? just_wait : kill_after_timeout,
> -#if defined(__EMX__) || defined(WIN32)
> -			   &script_out, &script_in, &script_err))) {
> -#else
> -			   &script_out, nph ? NULL : &script_in,
> -	    		   &script_err))) {
> -#endif
> +	  spawn_child_err_buff (r->main ? r->main->pool : r->pool, cgi_child,
> +				(void *)&cld,
> +				kill_after_timeout,
> +				&script_out, &script_in, &script_err))) {
>          log_reason ("couldn't spawn child process", r->filename, r);
>          return SERVER_ERROR;
>      }
> @@ -471,7 +461,7 @@
>  		dbpos += dbsize;
>  	    }
>  	    reset_timeout(r);
> -	    if (fwrite(argsbuffer, sizeof(char), len_read, script_out)
> +	    if (bwrite(script_out, argsbuffer, len_read)
>  	            < (size_t)len_read) {
>  	        /* silly script stopped reading, soak up remaining message */
>  	        while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
> @@ -480,20 +470,20 @@
>  	    }
>  	}
>  
> -	fflush (script_out);
> +	bflush (script_out);
>  	signal (SIGPIPE, handler);
>  	
>  	kill_timeout (r);
>      }
>      
> -    pfclose (r->main ? r->main->pool : r->pool, script_out);
> +    bclose(script_out);
>      
>      /* Handle script return... */
>      if (script_in && !nph) {
>          char *location, sbuf[MAX_STRING_LEN];
>  	int ret;
>        
> -        if ((ret = scan_script_header_err(r, script_in, sbuf)))
> +        if ((ret = scan_script_header_err_buff(r, script_in, sbuf)))
>  	    return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err);
>  	
>  	location = table_get (r->headers_out, "Location");
> @@ -502,11 +492,9 @@
>  	  
>  	    /* Soak up all the script output */
>  	    hard_timeout ("read from script", r);
> -	    while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_in)
> -	           > 0)
> +	    while (bgets(argsbuffer, HUGE_STRING_LEN, script_in))
>  	        continue;
> -	    while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err)
> -	           > 0)
> +	    while (bgets(argsbuffer, HUGE_STRING_LEN, script_err))
>  	        continue;
>  	    kill_timeout (r);
>  
> @@ -535,24 +523,20 @@
>  	
>  	send_http_header(r);
>  	if (!r->header_only)
> -	    send_fd(script_in, r);
> -	pfclose (r->main ? r->main->pool : r->pool, script_in);
> +	    send_fb(script_in, r);
>  
> -	/* Soak up stderr */
>  	soft_timeout("soaking script stderr", r);
> -	while (!r->connection->aborted &&
> -	  (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) > 0))
> -	    continue;
> +	while(bgets(argsbuffer, HUGE_STRING_LEN, script_err))
> +	      continue;
>  	kill_timeout(r);
> -	pfclose (r->main ? r->main->pool : r->pool, script_err);
> +	     
> +	bclose(script_in);
> +	bclose(script_out);
>      }
>  
> -    if (nph) {
> -#if defined(__EMX__) || defined(WIN32)
> -        while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
> -            bputs(argsbuffer, r->connection->client);
> -        }
> -#else
> +    if (script_in && nph) {
> +      send_fb(script_in, r);
> +#if !defined(__EMX__) && !defined(WIN32)
>  	waitpid(child_pid, (int*)0, 0);
>  #endif
>      }    
> Index: util_script.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.c,v
> retrieving revision 1.66
> diff -u -r1.66 util_script.c
> --- util_script.c	1997/07/15 21:39:59	1.66
> +++ util_script.c	1997/07/20 00:56:26
> @@ -312,7 +312,9 @@
>      }
>  }
>  
> -API_EXPORT(int) scan_script_header_err(request_rec *r, FILE *f, char *buffer)
> +
> +static int scan_script_header_err_core (request_rec *r, char *buffer,
> +    int (*getsfunc)(char *, int, void *), void *getsfunc_data)
>  {
>      char x[MAX_STRING_LEN];
>      char *w, *l;
> @@ -325,7 +327,7 @@
>      
>      while(1) {
>  
> -	if (fgets(w, MAX_STRING_LEN-1, f) == NULL) {
> +	if ((*getsfunc)(w, MAX_STRING_LEN-1, getsfunc_data) == 0) {
>  	    kill_timeout (r);
>  	    log_reason ("Premature end of script headers", r->filename, r);
>  	    return SERVER_ERROR;
> @@ -354,7 +356,7 @@
>  
>  	    if (!buffer)
>  	      /* Soak up all the script output --- may save an outright kill */
> -	      while (fgets(w, MAX_STRING_LEN-1, f) != NULL)
> +	      while ((*getsfunc)(w, MAX_STRING_LEN-1, getsfunc_data))
>  		continue;
>  	    
>  	    kill_timeout (r);
> @@ -401,6 +403,28 @@
>          }
>      }
>  }
> +
> +static int getsfunc_FILE (char *buf, int len, void *f)
> +{
> +    return fgets (buf, len, (FILE *)f) != NULL;
> +}
> +
> +API_EXPORT(int) scan_script_header_err(request_rec *r, FILE *f, char *buffer)
> +{
> +    return scan_script_header_err_core (r, buffer, getsfunc_FILE, f);
> +}
> +
> +static int getsfunc_BUFF (char *w, int len, void *fb)
> +{
> +    return bgets (w, len, (BUFF *)fb) > 0;
> +}
> +
> +API_EXPORT(int) scan_script_header_err_buff(request_rec *r, BUFF *fb,
> +    char *buffer)
> +{
> +    return scan_script_header_err_core (r, buffer, getsfunc_BUFF, fb);
> +}
> +
>  
>  API_EXPORT(void) send_size(size_t size, request_rec *r) {
>      char ss[20];
> Index: util_script.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.h,v
> retrieving revision 1.21
> diff -u -r1.21 util_script.h
> --- util_script.h	1997/07/15 21:40:00	1.21
> +++ util_script.h	1997/07/20 00:56:27
> @@ -64,6 +64,7 @@
>  API_EXPORT(void) add_common_vars(request_rec *r);
>  #define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL)
>  API_EXPORT(int) scan_script_header_err(request_rec *r, FILE *f, char *buffer);
> +API_EXPORT(int) scan_script_header_err_buff(request_rec *r, BUFF *f, char *buffer);
>  API_EXPORT(void) send_size(size_t size, request_rec *r);
>  API_EXPORT(int) call_exec (request_rec *r, char *argv0, char **env, int shellcmd);
>  
> 
> 
> 


-- 
====================================================================
      Jim Jagielski            |       jaguNET Access Services
     jim@jaguNET.com           |       http://www.jaguNET.com/
            "Look at me! I'm wearing a cardboard belt!"

Mime
View raw message