#ifdef HAVE_CONFIG_H #include #endif #include #include #include "../internal/syscall.h" /* * select: plain POSIX select over SYS_pselect6. The kernel wants a struct * timespec, so the struct timeval timeout is converted here (NULL passes * through as "block indefinitely") and the sigset pair stays NULL: select * never changes the signal mask. select() and pselect() share this syscall * on Linux; the 6th argument of pselect6 is a { sigset_t *, size_t } pair * pointer that is NULL when the mask is left alone. */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { struct timespec ts; struct timespec *tsp = NULL; if (timeout != NULL) { if (timeout->tv_sec < 0 || timeout->tv_usec < 0 || timeout->tv_usec >= 1000000L) { errno = EINVAL; return -1; } ts.tv_sec = timeout->tv_sec; ts.tv_nsec = (long)timeout->tv_usec * 1000; tsp = &ts; } return syscall_ret(__syscall6(SYS_pselect6, (long)nfds, (long)readfds, (long)writefds, (long)exceptfds, (long)tsp, 0L)); }