| Summary: | libc_r: possible for select(2) to return ok with no bit set | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Archie Cobbs <archie> | ||||
| Component: | bin | Assignee: | Archie Cobbs <archie> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.5-RELEASE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
Responsible Changed From-To: freebsd-bugs->archie I'm working on this bug. State Changed From-To: open->closed Fixed in -current and -stable by revisions 1.21 and 1.16.2.2 of src/lib/libc_r/uthread/uthread_select.c. |
The libc_r version of select(2) doesn't check for error conditions on the file descriptor for readability or writability. So it's possible for select() to return zero, yet no file descriptor bits are set. How-To-Repeat: Compile and run this program first linking with libc, then with libc_r: $ cc -Wall -o xx xx.c $ cc -Wall -o xxp xx.c -D_THREAD_SAFE -pthread $ ./xx press ctrl-c... ^Cxx: select: Bad file descriptor $ ./xxp press ctrl-c... ^Cstdin readable=0 Notice in the second case, select() returned OK but stdin was not marked readable. ============================== CUT HERE ================================ #ifdef __linux__ #define _XOPEN_SOURCE 600 #define _GNU_SOURCE 1 #define _BSD_SOURCE 1 #define _ISOC99_SOURCE 1 #endif #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <time.h> #include <err.h> static void handler(int sig); int main(int ac, char **av) { fd_set fds; printf("press ctrl-c...\n"); signal(SIGINT, handler); FD_ZERO(&fds); FD_SET(0, &fds); while (1) { if (select(1, &fds, NULL, NULL, NULL) == -1) { if (errno != EINTR) err(1, "select"); continue; } break; } printf("stdin readable=%d\n", FD_ISSET(0, &fds) != 0); /* Done */ return (0); } static void handler(int sig) { if (close(0) == -1) err(1, "close"); } ============================== CUT HERE ================================