httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Roy Fielding <field...@hyperreal.com>
Subject cvs commit: apache/src CHANGES buff.c http_main.h http_main.c http_protocol.c mod_cgi.c
Date Mon, 21 Apr 1997 20:29:13 GMT
fielding    97/04/21 13:29:13

  Modified:    src       CHANGES buff.c http_main.h http_main.c
                        http_protocol.c  mod_cgi.c
  Log:
  If a soft timeout (or lingerout) occurs while trying to flush a
  buffer or write inside buff.c or fread'ing from a CGI's output,
  then the timeout would be ignored.  This fix is rather nasty,
  since what we would really like to do is flush the output if we
  timeout on a read, but we can't do that without differentiating
  between read and write timeouts, and we can't do that without
  rewriting most of the server.
  
  What we really need is a global (per-thread) timeout that sets a
  single flag, and then have all of our code check for that flag and
  recover gracefully based upon what it was trying to do at the time.
  However, that might be subject to race conditions as well, so we
  might just need to replace all of our generic timeouts with more
  sophisticated timeouts, each with its own sigsetjmp handling.
  Something to remember for 2.0.
  
  Reviewed by: Randy Terbush, Chuck Murcko, Dean Gaudet
  
  Revision  Changes    Path
  1.239     +4 -0      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.238
  retrieving revision 1.239
  diff -C3 -r1.238 -r1.239
  *** CHANGES	1997/04/20 04:02:07	1.238
  --- CHANGES	1997/04/21 20:29:06	1.239
  ***************
  *** 1,5 ****
  --- 1,9 ----
    Changes with Apache 1.2
    
  +   *) If a soft timeout (or lingerout) occurs while trying to flush a
  +      buffer or write inside buff.c or fread'ing from a CGI's output,
  +      then the timeout would be ignored. [Roy Fielding] PR#373
  + 
      *) Work around a bug in Netscape Navigator versions 2.x, 3.x and 4.0b2's
         parsing of headers.  If the terminating empty-line CRLF occurs starting
         at the 256th or 257th byte of output, then Navigator will think a normal
  
  
  
  1.24      +93 -76    apache/src/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/buff.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -C3 -r1.23 -r1.24
  *** buff.c	1997/03/04 21:44:38	1.23
  --- buff.c	1997/04/21 20:29:07	1.24
  ***************
  *** 191,201 ****
        char chunksize[16];	/* Big enough for practically anything */
        int chunk_header_size;
    
  !     if( fb->outchunk != -1 ) {
    	/* already chunking */
    	return;
        }
  !     if( !(fb->flags & B_WR) ) {
    	/* unbuffered writes */
    	return;
        }
  --- 191,201 ----
        char chunksize[16];	/* Big enough for practically anything */
        int chunk_header_size;
    
  !     if (fb->outchunk != -1) {
    	/* already chunking */
    	return;
        }
  !     if (!(fb->flags & B_WR) || (fb->flags & (B_WRERR|B_EOUT))) {
    	/* unbuffered writes */
    	return;
        }
  ***************
  *** 609,630 ****
     * This is *seriously broken* if used on a non-blocking fd.  It will poll.
     */
    static int
  ! write_it_all( int fd, const void *buf, int nbyte ) {
  ! 
        int i;
    
  !     while( nbyte > 0 ) {
  ! 	i = write( fd, buf, nbyte );
  ! 	if( i == -1 ) {
  ! 	    if( errno != EAGAIN && errno != EINTR ) {
  ! 		return( -1 );
    	    }
  ! 	} else {
    	    nbyte -= i;
    	    buf = i + (const char *)buf;
    	}
        }
  !     return( 0 );
    }
    
    
  --- 609,636 ----
     * This is *seriously broken* if used on a non-blocking fd.  It will poll.
     */
    static int
  ! write_it_all(BUFF *fb, const void *buf, int nbyte)
  ! {
        int i;
    
  !     if (fb->flags & (B_WRERR|B_EOUT))
  ! 	return -1;
  ! 
  !     while (nbyte > 0) {
  ! 	i = write(fb->fd, buf, nbyte);
  ! 	if (i < 0) {
  ! 	    if (errno != EAGAIN && errno != EINTR) {
  ! 		return -1;
    	    }
  ! 	}
  ! 	else {
    	    nbyte -= i;
    	    buf = i + (const char *)buf;
    	}
  + 	if (fb->flags & B_EOUT)
  + 	    return -1;
        }
  !     return 0;
    }
    
    
  ***************
  *** 635,665 ****
     * 2.0, using something like sfio stacked disciplines or BSD's funopen().
     */
    static int
  ! bcwrite(BUFF *fb, const void *buf, int nbyte) {
  ! 
        char chunksize[16];	/* Big enough for practically anything */
    #ifndef NO_WRITEV
        struct iovec vec[3];
        int i, rv;
    #endif
    
  !     if( !(fb->flags & B_CHUNK) ) return write( fb->fd, buf, nbyte );
    
    #ifdef NO_WRITEV
        /* without writev() this has poor performance, too bad */
    
        ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012", nbyte);
  !     if( write_it_all(fb->fd, chunksize, strlen(chunksize)) == -1 ) {
  ! 	return( -1 );
  !     }
  !     if( write_it_all(fb->fd, buf, nbyte) == -1 ) {
  ! 	return( -1 );
  !     }
  !     if( write_it_all(fb->fd, "\015\012", 2) == -1 ) {
  ! 	return( -1 );
  !     }
  !     return( nbyte );
    #else
    #define NVEC	(sizeof(vec)/sizeof(vec[0]))
    
        vec[0].iov_base = chunksize;
  --- 641,673 ----
     * 2.0, using something like sfio stacked disciplines or BSD's funopen().
     */
    static int
  ! bcwrite(BUFF *fb, const void *buf, int nbyte)
  ! {
        char chunksize[16];	/* Big enough for practically anything */
    #ifndef NO_WRITEV
        struct iovec vec[3];
        int i, rv;
    #endif
    
  !     if (fb->flags & (B_WRERR|B_EOUT))
  ! 	return -1;
  ! 
  !     if (!(fb->flags & B_CHUNK))
  ! 	return write(fb->fd, buf, nbyte);
    
    #ifdef NO_WRITEV
        /* without writev() this has poor performance, too bad */
    
        ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012", nbyte);
  !     if (write_it_all(fb, chunksize, strlen(chunksize)) == -1)
  ! 	return -1;
  !     if (write_it_all(fb, buf, nbyte) == -1)
  ! 	return -1;
  !     if (write_it_all(fb, "\015\012", 2) == -1)
  ! 	return -1;
  !     return nbyte;
    #else
  + 
    #define NVEC	(sizeof(vec)/sizeof(vec[0]))
    
        vec[0].iov_base = chunksize;
  ***************
  *** 674,685 ****
         */
        for( i = 0; i < NVEC; ) {
    	do rv = writev( fb->fd, &vec[i], NVEC - i );
  ! 	while ( rv == -1 && errno == EINTR );
  ! 	if( rv == -1 ) {
  ! 	    return( -1 );
  ! 	}
    	/* recalculate vec to deal with partial writes */
  ! 	while( rv > 0 ) {
    	    if( rv <= vec[i].iov_len ) {
    		vec[i].iov_base = (char *)vec[i].iov_base + rv;
    		vec[i].iov_len -= rv;
  --- 682,692 ----
         */
        for( i = 0; i < NVEC; ) {
    	do rv = writev( fb->fd, &vec[i], NVEC - i );
  ! 	while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
  ! 	if (rv == -1)
  ! 	    return -1;
    	/* recalculate vec to deal with partial writes */
  ! 	while (rv > 0) {
    	    if( rv <= vec[i].iov_len ) {
    		vec[i].iov_base = (char *)vec[i].iov_base + rv;
    		vec[i].iov_len -= rv;
  ***************
  *** 692,700 ****
    		++i;
    	    }
    	}
        }
        /* if we got here, we wrote it all */
  !     return( nbyte );
    #undef NVEC
    #endif
    }
  --- 699,709 ----
    		++i;
    	    }
    	}
  + 	if (fb->flags & B_EOUT)
  + 	    return -1;
        }
        /* if we got here, we wrote it all */
  !     return nbyte;
    #undef NVEC
    #endif
    }
  ***************
  *** 720,734 ****
    /* unbuffered write -- have to use bcwrite since we aren't taking care
     * of chunking any other way */
    	do i = bcwrite(fb, buf, nbyte);
  ! 	while (i == -1 && errno == EINTR);
  ! 	if (i > 0) fb->bytes_sent += i;
  ! 	if (i == 0)
  ! 	{
  ! 	    i = -1;  /* return of 0 means non-blocking */
    	    errno = EAGAIN;
    	}
  ! 	if (i == -1 && errno != EAGAIN) doerror(fb, B_WR);
  ! 	return i;
        }
    
    /*
  --- 729,749 ----
    /* unbuffered write -- have to use bcwrite since we aren't taking care
     * of chunking any other way */
    	do i = bcwrite(fb, buf, nbyte);
  ! 	while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
  ! 	if (i == 0) {  /* return of 0 means non-blocking */
    	    errno = EAGAIN;
  + 	    return -1;
    	}
  ! 	else if (i < 0) {
  ! 	    if (errno != EAGAIN)
  ! 	        doerror(fb, B_WR);
  ! 	    return -1;
  ! 	}
  ! 	fb->bytes_sent += i;
  ! 	if (fb->flags & B_EOUT)
  ! 	    return -1;
  ! 	else
  ! 	    return i;
        }
    
    /*
  ***************
  *** 752,783 ****
    	}
    
    /* the buffer must be full */
  ! 	if( fb->flags & B_CHUNK ) {
    	    end_chunk(fb);
    	    /* it is just too painful to try to re-cram the buffer while
    	     * chunking
    	     */
  ! 	    i = write_it_all( fb->fd, fb->outbase, fb->outcnt )
  ! 		    ? -1 : fb->outcnt;
  ! 	} else {
  ! 	    do i = write(fb->fd, fb->outbase, fb->outcnt);
  ! 	    while (i == -1 && errno == EINTR);
    	}
  ! 	if (i > 0) fb->bytes_sent += i;
  ! 	if (i == 0)
  ! 	{
  ! 	    i = -1;  /* return of 0 means non-blocking */
  ! 	    errno = EAGAIN;
    	}
  ! 	if (i == -1)
  ! 	{
  ! 	    if (nwr == 0)
  ! 	    {
    		if (errno != EAGAIN) doerror(fb, B_WR);
    		return -1;
    	    }
    	    else return nwr;
    	}
    
    	/* deal with a partial write */
    	if (i < fb->outcnt)
  --- 767,794 ----
    	}
    
    /* the buffer must be full */
  ! 	if (fb->flags & B_CHUNK) {
    	    end_chunk(fb);
    	    /* it is just too painful to try to re-cram the buffer while
    	     * chunking
    	     */
  ! 	    i = (write_it_all(fb, fb->outbase, fb->outcnt) == -1) ?
  ! 	            -1 : fb->outcnt;
    	}
  ! 	else {
  ! 	    do i = write(fb->fd, fb->outbase, fb->outcnt);
  ! 	    while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
    	}
  ! 	if (i <= 0) {
  ! 	    if (i == 0) /* return of 0 means non-blocking */
  ! 	        errno = EAGAIN;
  ! 	    if (nwr == 0) {
    		if (errno != EAGAIN) doerror(fb, B_WR);
    		return -1;
    	    }
    	    else return nwr;
    	}
  + 	fb->bytes_sent += i;
    
    	/* deal with a partial write */
    	if (i < fb->outcnt)
  ***************
  *** 786,793 ****
    	    unsigned char *x=fb->outbase;
    	    for (j=i; j < n; j++) x[j-i] = x[j];
    	    fb->outcnt -= i;
  ! 	} else
    	    fb->outcnt = 0;
        }
    /* we have emptied the file buffer. Now try to write the data from the
     * original buffer until there is less than bufsiz left.  Note that we
  --- 797,808 ----
    	    unsigned char *x=fb->outbase;
    	    for (j=i; j < n; j++) x[j-i] = x[j];
    	    fb->outcnt -= i;
  ! 	}
  ! 	else
    	    fb->outcnt = 0;
  + 
  + 	if (fb->flags & B_EOUT)
  + 	    return -1;
        }
    /* we have emptied the file buffer. Now try to write the data from the
     * original buffer until there is less than bufsiz left.  Note that we
  ***************
  *** 797,822 ****
        while (nbyte >= fb->bufsiz)
        {
    	do i = bcwrite(fb, buf, nbyte);
  ! 	while (i == -1 && errno == EINTR);
  ! 	if (i > 0) fb->bytes_sent += i;
  ! 	if (i == 0)
  ! 	{
  ! 	    i = -1;  /* return of 0 means non-blocking */
  ! 	    errno = EAGAIN;
  ! 	}
  ! 	if (i == -1)
  ! 	{
  ! 	    if (nwr == 0)
  ! 	    {
    		if (errno != EAGAIN) doerror(fb, B_WR);
    		return -1;
    	    }
    	    else return nwr;
    	}
    
    	buf = i + (const char *)buf;
    	nwr += i;
    	nbyte -= i;
        }
    /* copy what's left to the file buffer */
        fb->outcnt = 0;
  --- 812,835 ----
        while (nbyte >= fb->bufsiz)
        {
    	do i = bcwrite(fb, buf, nbyte);
  ! 	while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
  ! 	if (i <= 0) {
  ! 	    if (i == 0) /* return of 0 means non-blocking */
  ! 	        errno = EAGAIN;
  ! 	    if (nwr == 0) {
    		if (errno != EAGAIN) doerror(fb, B_WR);
    		return -1;
    	    }
    	    else return nwr;
    	}
  + 	fb->bytes_sent += i;
    
    	buf = i + (const char *)buf;
    	nwr += i;
    	nbyte -= i;
  + 
  + 	if (fb->flags & B_EOUT)
  + 	    return -1;
        }
    /* copy what's left to the file buffer */
        fb->outcnt = 0;
  ***************
  *** 840,868 ****
    
        if (fb->flags & B_WRERR) return -1;
        
  !     if( fb->flags & B_CHUNK ) end_chunk(fb);
    
        while (fb->outcnt > 0)
        {
  ! /* the buffer must be full */
    	do i = write(fb->fd, fb->outbase, fb->outcnt);
  ! 	while (i == -1 && errno == EINTR);
  ! 	if (i > 0) fb->bytes_sent += i;
  ! 	if (i == 0)
  ! 	{
    	    errno = EAGAIN;
    	    return -1;  /* return of 0 means non-blocking */
    	}
  ! 	if (i == -1)
  ! 	{
    	    if (errno != EAGAIN) doerror(fb, B_WR);
    	    return -1;
    	}
    
  ! /*
  !  * we should have written all the data, however if the fd was in a
  !  * strange (non-blocking) mode, then we might not have done so.
  !  */
    	if (i < fb->outcnt)
    	{
    	    int j, n=fb->outcnt;
  --- 853,879 ----
    
        if (fb->flags & B_WRERR) return -1;
        
  !     if (fb->flags & B_CHUNK) end_chunk(fb);
    
        while (fb->outcnt > 0)
        {
  ! 	/* the buffer must be full */
    	do i = write(fb->fd, fb->outbase, fb->outcnt);
  ! 	while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
  ! 	if (i == 0) {
    	    errno = EAGAIN;
    	    return -1;  /* return of 0 means non-blocking */
    	}
  ! 	else if (i < 0) {
    	    if (errno != EAGAIN) doerror(fb, B_WR);
    	    return -1;
    	}
  + 	fb->bytes_sent += i;
    
  ! 	/*
  !  	 * We should have written all the data, but if the fd was in a
  !  	 * strange (non-blocking) mode, then we might not have done so.
  !  	 */
    	if (i < fb->outcnt)
    	{
    	    int j, n=fb->outcnt;
  ***************
  *** 870,875 ****
  --- 881,892 ----
    	    for (j=i; j < n; j++) x[j-i] = x[j];
    	}
    	fb->outcnt -= i;
  + 
  + 	/* If a soft timeout occurs while flushing, the handler should
  + 	 * have set the buffer flag B_EOUT.
  + 	 */
  + 	if (fb->flags & B_EOUT)
  + 	    return -1;
        }
        return 0;
    }
  
  
  
  1.9       +14 -0     apache/src/http_main.h
  
  Index: http_main.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.h,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -C3 -r1.8 -r1.9
  *** http_main.h	1997/01/01 18:10:20	1.8
  --- http_main.h	1997/04/21 20:29:07	1.9
  ***************
  *** 96,98 ****
  --- 96,112 ----
    int get_child_status (int child_num);
    int count_busy_servers ();
    int count_idle_servers ();
  + 
  + /*
  +  * Replace signal function with sigaction equivalent
  +  */
  + #ifndef NO_USE_SIGACTION
  + typedef void Sigfunc(int);
  + 
  + #if defined(SIG_IGN) && !defined(SIG_ERR)
  + #define SIG_ERR ((Sigfunc *)-1)
  + #endif
  + 
  + Sigfunc *signal(int signo, Sigfunc *func);
  + #endif
  + 
  
  
  
  1.138     +44 -18    apache/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.c,v
  retrieving revision 1.137
  retrieving revision 1.138
  diff -C3 -r1.137 -r1.138
  *** http_main.c	1997/04/12 04:24:57	1.137
  --- http_main.c	1997/04/21 20:29:07	1.138
  ***************
  *** 325,332 ****
    static int alarms_blocked = 0;
    static int alarm_pending = 0;
    
  ! void timeout(sig)			/* Also called on SIGPIPE */
  ! int sig;
    {
        char errstr[MAX_STRING_LEN];
        void *dirconf;
  --- 325,353 ----
    static int alarms_blocked = 0;
    static int alarm_pending = 0;
    
  ! #ifndef NO_USE_SIGACTION
  ! /*
  !  * Replace standard signal() with the more reliable sigaction equivalent
  !  * from W. Richard Stevens' "Advanced Programming in the UNIX Environment"
  !  * (the version that does not automatically restart system calls).
  !  */
  ! Sigfunc *signal(int signo, Sigfunc *func)
  ! {
  !     struct sigaction act, oact;
  ! 
  !     act.sa_handler = func;
  !     sigemptyset(&act.sa_mask);
  !     act.sa_flags = 0;
  ! #ifdef  SA_INTERRUPT    /* SunOS */
  !     act.sa_flags |= SA_INTERRUPT;
  ! #endif
  !     if (sigaction(signo, &act, &oact) < 0)
  !        return SIG_ERR;
  !     return oact.sa_handler;
  ! }
  ! #endif
  ! 
  ! void timeout(int sig)			/* Also called on SIGPIPE */
    {
        char errstr[MAX_STRING_LEN];
        void *dirconf;
  ***************
  *** 376,383 ****
    	if (!current_conn->keptalive) 
                log_transaction(log_req);
    
  !         if (sig == SIGPIPE)
  !             bsetflag(timeout_req->connection->client, B_EOUT, 1);
    	bclose(timeout_req->connection->client);
        
    	if (!standalone) exit(0);
  --- 397,403 ----
    	if (!current_conn->keptalive) 
                log_transaction(log_req);
    
  ! 	bsetflag(timeout_req->connection->client, B_EOUT, 1);
    	bclose(timeout_req->connection->client);
        
    	if (!standalone) exit(0);
  ***************
  *** 388,397 ****
    #endif
        }
        else {   /* abort the connection */
  !         if (sig == SIGPIPE)
  !             bsetflag(current_conn->client, B_EOUT, 1);
  !         else
  !             bflush(current_conn->client);
            current_conn->aborted = 1;
        }
    }
  --- 408,414 ----
    #endif
        }
        else {   /* abort the connection */
  !         bsetflag(current_conn->client, B_EOUT, 1);
            current_conn->aborted = 1;
        }
    }
  ***************
  *** 419,425 ****
        timeout_req = r;
        timeout_name = name;
        
  !     signal(SIGALRM,(void (*)())timeout);
        if (r->connection->keptalive) 
           alarm (r->server->keep_alive_timeout);
        else
  --- 436,442 ----
        timeout_req = r;
        timeout_name = name;
        
  !     signal(SIGALRM, timeout);
        if (r->connection->keptalive) 
           alarm (r->server->keep_alive_timeout);
        else
  ***************
  *** 431,437 ****
        timeout_req = r;
        timeout_name = name;
        
  !     signal(SIGALRM,(void (*)())timeout);
        alarm (r->server->timeout);
    }
    
  --- 448,454 ----
        timeout_req = r;
        timeout_name = name;
        
  !     signal(SIGALRM, timeout);
        alarm (r->server->timeout);
    }
    
  ***************
  *** 439,445 ****
    {
        timeout_name = name;
        
  !     signal(SIGALRM,(void (*)())timeout);
        alarm (r->server->timeout);
    }
    
  --- 456,462 ----
    {
        timeout_name = name;
        
  !     signal(SIGALRM, timeout);
        alarm (r->server->timeout);
    }
    
  ***************
  *** 483,488 ****
  --- 500,509 ----
     * calls to shutdown only half of the connection.  You should define
     * NO_LINGCLOSE in conf.h if such is the case for your system.
     */
  + #ifndef MAX_SECS_TO_LINGER
  + #define MAX_SECS_TO_LINGER 30
  + #endif
  + 
    #ifdef USE_SO_LINGER
    #define NO_LINGCLOSE    /* The two lingering options are exclusive */
    
  ***************
  *** 491,497 ****
        struct linger li;
    
        li.l_onoff = 1;
  !     li.l_linger = 30;
    
        if (setsockopt(s, SOL_SOCKET, SO_LINGER,
                       (char *)&li, sizeof(struct linger)) < 0) {
  --- 512,518 ----
        struct linger li;
    
        li.l_onoff = 1;
  !     li.l_linger = MAX_SECS_TO_LINGER;
    
        if (setsockopt(s, SOL_SOCKET, SO_LINGER,
                       (char *)&li, sizeof(struct linger)) < 0) {
  ***************
  *** 523,539 ****
    	siglongjmp(jmpbuffer,1);
    #endif
        }
        current_conn->aborted = 1;
    }
        
    static void linger_timeout ()
    {
  -     const int max_secs_to_linger = 30;
  - 
        timeout_name = "lingering close";
        
  !     signal(SIGALRM,(void (*)())lingerout);
  !     alarm(max_secs_to_linger);
    }
    
    /* Since many clients will abort a connection instead of closing it,
  --- 544,559 ----
    	siglongjmp(jmpbuffer,1);
    #endif
        }
  +     bsetflag(current_conn->client, B_EOUT, 1);
        current_conn->aborted = 1;
    }
        
    static void linger_timeout ()
    {
        timeout_name = "lingering close";
        
  !     signal(SIGALRM, lingerout);
  !     alarm(MAX_SECS_TO_LINGER);
    }
    
    /* Since many clients will abort a connection instead of closing it,
  ***************
  *** 556,562 ****
    
        /* Send any leftover data to the client, but never try to again */
    
  !     bflush(r->connection->client);
        bsetflag(r->connection->client, B_EOUT, 1);
    
        /* Close our half of the connection --- send the client a FIN */
  --- 576,586 ----
    
        /* Send any leftover data to the client, but never try to again */
    
  !     if (bflush(r->connection->client) == -1) {
  !         kill_timeout(r);
  !         bclose(r->connection->client);
  !         return;
  !     }
        bsetflag(r->connection->client, B_EOUT, 1);
    
        /* Close our half of the connection --- send the client a FIN */
  ***************
  *** 1435,1441 ****
    {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
  !     memset(&sa,0,sizeof sa);
    
        if (!one_process) {
    	sa.sa_handler = (void (*)())seg_fault;
  --- 1459,1467 ----
    {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
  ! 
  !     sigemptyset(&sa.sa_mask);
  !     sa.sa_flags = 0;
    
        if (!one_process) {
    	sa.sa_handler = (void (*)())seg_fault;
  
  
  
  1.115     +4 -5      apache/src/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_protocol.c,v
  retrieving revision 1.114
  retrieving revision 1.115
  diff -C3 -r1.114 -r1.115
  *** http_protocol.c	1997/04/20 04:02:08	1.114
  --- http_protocol.c	1997/04/21 20:29:08	1.115
  ***************
  *** 1252,1259 ****
    {
        /* Turn off chunked encoding */
    
  !     if (r->chunked) {
  !         hard_timeout("send ending chunk", r);
            bsetflag(r->connection->client, B_CHUNK, 0);
    	bputs("0\015\012", r->connection->client);
    	/* If we had footer "headers", we'd send them now */
  --- 1252,1259 ----
    {
        /* Turn off chunked encoding */
    
  !     if (r->chunked && !r->connection->aborted) {
  !         soft_timeout("send ending chunk", r);
            bsetflag(r->connection->client, B_CHUNK, 0);
    	bputs("0\015\012", r->connection->client);
    	/* If we had footer "headers", we'd send them now */
  ***************
  *** 1519,1525 ****
        char buf[IOBUFSIZE];
        long total_bytes_sent = 0;
        register int n, w, o, len;
  -     conn_rec *c = r->connection;
        
        if (length == 0) return 0;
    
  --- 1519,1524 ----
  ***************
  *** 1531,1537 ****
    	else len = IOBUFSIZE;
    
            while ((n= fread(buf, sizeof(char), len, f)) < 1
  ! 	       && ferror(f) && errno == EINTR)
    	    continue;
    	
    	if (n < 1) {
  --- 1530,1536 ----
    	else len = IOBUFSIZE;
    
            while ((n= fread(buf, sizeof(char), len, f)) < 1
  ! 	       && ferror(f) && errno == EINTR && !r->connection->aborted)
    	    continue;
    	
    	if (n < 1) {
  ***************
  *** 1541,1547 ****
    	total_bytes_sent += n;
    	
            while(n && !r->connection->aborted) {
  !             w=bwrite(c->client, &buf[o], n);
    	    if(w <= 0)
    		break;
    	    reset_timeout(r); /* reset timeout after successful write */
  --- 1540,1546 ----
    	total_bytes_sent += n;
    	
            while(n && !r->connection->aborted) {
  !             w=bwrite(r->connection->client, &buf[o], n);
    	    if(w <= 0)
    		break;
    	    reset_timeout(r); /* reset timeout after successful write */
  
  
  
  1.39      +10 -7     apache/src/mod_cgi.c
  
  Index: mod_cgi.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -C3 -r1.38 -r1.39
  *** mod_cgi.c	1997/04/16 19:49:59	1.38
  --- mod_cgi.c	1997/04/21 20:29:09	1.39
  ***************
  *** 459,466 ****
    		dbpos += dbsize;
    	    }
    	    reset_timeout(r);
  ! 	    if (fwrite(argsbuffer, 1, len_read, script_out) < (size_t)len_read) {
  ! 		/* silly script stopped reading, soak up remaining message */
    	        while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
    	            ; /* dump it */
    	        break;
  --- 459,467 ----
    		dbpos += dbsize;
    	    }
    	    reset_timeout(r);
  ! 	    if (fwrite(argsbuffer, sizeof(char), len_read, script_out)
  ! 	            < (size_t)len_read) {
  ! 	        /* silly script stopped reading, soak up remaining message */
    	        while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
    	            ; /* dump it */
    	        break;
  ***************
  *** 489,498 ****
    	  
    	    /* Soak up all the script output */
    	    hard_timeout ("read from script", r);
  ! 	    while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL)
    	        continue;
  - 	    while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
  - 	      continue;
    	    kill_timeout (r);
    
    
  --- 490,501 ----
    	  
    	    /* Soak up all the script output */
    	    hard_timeout ("read from script", r);
  ! 	    while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_in)
  ! 	           > 0)
  ! 	        continue;
  ! 	    while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err)
  ! 	           > 0)
    	        continue;
    	    kill_timeout (r);
    
    
  ***************
  *** 525,532 ****
    
    	/* Soak up stderr */
    	soft_timeout("soaking script stderr", r);
  ! 	while ((fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL) &&
  ! 	       !r->connection->aborted)
    	    continue;
    	kill_timeout(r);
    	pfclose (r->main ? r->main->pool : r->pool, script_err);
  --- 528,535 ----
    
    	/* Soak up stderr */
    	soft_timeout("soaking script stderr", r);
  ! 	while (!r->connection->aborted &&
  ! 	  (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) > 0))
    	    continue;
    	kill_timeout(r);
    	pfclose (r->main ? r->main->pool : r->pool, script_err);
  
  
  

Mime
View raw message