mogul@Gregorio.ARPA (05/14/85)
Index: sys/sys/sys_generic.c 4.2BSD Description: If select() is called with a null pointer for the "timeout" argument, and then interrupted, it fails to modify the bit mask arguments, thus implying that all descriptors are ready (although they may not be). If the timeout argument is specified, select() behaves the way one would expect, setting all the masks to zero before returning. This inconsistency is not documented. To be fair to the implementer, neither the manual page nor the "4.2 System Manual" specifies what select() should do when it is interrupted. Repeat-By: Run this program: #include <sys/time.h> #include <signal.h> catcher(){} main() { struct timeval tv; int fd; signal(SIGALRM, catcher); fd = 1; tv.tv_sec = 10; tv.tv_usec = 0; alarm(2); select(1, &fd, 0, 0, &tv); printf("with tv: %d\n", fd); signal(SIGALRM, catcher); fd = 1; alarm(2); select(1, &fd, 0, 0, 0); printf("no tv: %d\n", fd); } It prints: with tv: 0 no tv: 1 Suggested Fix (untested!): In the select() function in sys/sys/sys_generic.c, some attempt is made to clean up after an interrupt IF a timeout is specified. A similar clean-up should be done even if no timeout is specified. I don't feel like trying to test this fix, since I have a workaround in my program. However, I believe this version of the code (between the "lqsave = u.u_qsave" and the "splx(s)" of the original code) should work. lqsave = u.u_qsave; if (setjmp(&u.u_qsave)) { if (uap->tv) untimeout(unselect, (caddr_t)u.u_procp); u.u_error = EINTR; splx(s); goto done; } if (uap->tv) timeout(unselect, (caddr_t)u.u_procp, hzto(&atv)); sleep((caddr_t)&selwait, PZERO+1); u.u_qsave = lqsave; if (uap->tv) untimeout(unselect, (caddr_t)u.u_procp); splx(s);
matt@oddjob.UUCP (Matt Crawford) (05/17/85)
In article <163@Gregorio.ARPA> mogul@Gregorio.ARPA writes: > >Description: > If select() is called with a null pointer for the "timeout" > argument, and then interrupted, it fails to modify the > bit mask arguments, thus implying that all descriptors > are ready (although they may not be). > .... If you do not test the return value of select() your program is wrong. Only use the mask values if the return value is strictly greater than 0. The manual page says that it is a bug that the masks are ever modified when select times out. The same comment should also be made about interrupts. In fact, the pyramid does not have this bug. _____________________________________________________ Matt University crawford@anl-mcs.arpa Crawford of Chicago ihnp4!oddjob!matt