feat(select): poll/select and fd_set
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#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));
|
||||
}
|
||||
Reference in New Issue
Block a user