fielding 98/10/05 10:48:45
Modified: src CHANGES src/main buff.c Log: Fix a possible race condition between timed-out requests and the ap_bhalfduplex select that might result in an infinite loop on platforms that do not validate the descriptor. Revision Changes Path 1.1101 +4 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1100 retrieving revision 1.1101 diff -u -r1.1100 -r1.1101 --- CHANGES 1998/10/04 19:05:13 1.1100 +++ CHANGES 1998/10/05 17:48:42 1.1101 @@ -1,5 +1,9 @@ Changes with Apache 1.3.3 + *) Fix a possible race condition between timed-out requests and the + ap_bhalfduplex select that might result in an infinite loop on + platforms that do not validate the descriptor. [Roy Fielding] + *) Fix mod_autoindex bug where directories got a size of "0k" instead of "-". [Martin Plechsmid <[EMAIL PROTECTED]>, Marc Slemko] PR#3130 1.83 +12 -3 apache-1.3/src/main/buff.c Index: buff.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/buff.c,v retrieving revision 1.82 retrieving revision 1.83 diff -u -r1.82 -r1.83 --- buff.c 1998/09/04 16:47:46 1.82 +++ buff.c 1998/10/05 17:48:44 1.83 @@ -562,14 +562,22 @@ #endif -/* note we assume the caller has ensured that fb->fd_in <= FD_SETSIZE */ +/* Test the descriptor and flush the output buffer if it looks like + * we will block on the next read. + * + * Note we assume the caller has ensured that fb->fd_in <= FD_SETSIZE + */ API_EXPORT(void) ap_bhalfduplex(BUFF *fb) { int rv; fd_set fds; struct timeval tv; - if (fb->incnt > 0 || fb->outcnt == 0) { + /* We don't need to do anything if the connection has been closed + * or there is something readable in the incoming buffer + * or there is nothing flushable in the output buffer. + */ + if (fb == NULL || fb->fd_in < 0 || fb->incnt > 0 || fb->outcnt == 0) { return; } /* test for a block */ @@ -579,7 +587,8 @@ tv.tv_sec = 0; tv.tv_usec = 0; rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv); - } while (rv < 0 && errno == EINTR); + } while (rv < 0 && errno == EINTR && !(fb->flags & B_EOUT)); + /* treat any error as if it would block as well */ if (rv != 1) { ap_bflush(fb);