stevo@elroy.jpl.nasa.gov (Steve Groom) (02/01/91)
I found this in the NNTP 1.5.10 server/serve.c source. I don't know if it's
been discussed before.
----- server/serve.c, line 256
#ifdef TIMEOUT
/* Do timeout with select() (i.e. the intelligent way) */
FD_ZERO(&readfds);
FD_SET(fileno(stdin), &readfds);
errno = 0;
***> i = select(fileno(stdin) + 1,
&readfds, (fd_set*)0, (fd_set*)0, &timeout);
if (i < 0) {
/* "Interrupted system call" isn't a real error */
if (errno == EINTR)
continue;
syslog(LOG_ERR, "%s read select: %m", hostname);
break;
}
if (!FD_ISSET(fileno(stdin), &readfds)) {
printf(
"%d Timeout after %d seconds, closing connection.\r\n",
ERR_FAULT, TIMEOUT);
(void) fflush(stdout);
#ifdef LOG
syslog(LOG_ERR, "%s timeout", hostname);
#endif LOG
exit(1);
}
#endif
***> if (fgets(line, sizeof(line), stdin) == NULL)
break;
--------------------
The problem: You shouldn't use select() to determine if stdin is ready to
for reading. There may be characters in the stdio buffer for stdin
that have not yet been read, and this code only uses select() to look
at the file descriptor. If so, the select() may time out even though
stdin could have been successfully read.
In reality, stdin is usually line buffered so it's not that big a deal,
because at this point in the code we're looking to read a whole new
line.
It doesn't look like an easy problem to do right, but this solution looks
like it might cause problems.
-steve
--
Steve Groom, Jet Propulsion Laboratory, Pasadena, CA
stevo@elroy.jpl.nasa.gov {ames,usc}!elroy!stevosob@tmc.edu (Stan Barber) (02/01/91)
Fixed in 1.5.11.
--
Stan internet: sob@bcm.tmc.edu Director, Networking
Olan uucp: {rutgers,mailrus}!bcm!sob and Systems Support
Barber Opinions expressed are only mine. Baylor College of Medicine