Alternative I/O Models 1369
file descriptor that is monitored (along with other file descriptors) using
select(), poll(), or epoll_wait().
63.5.1 The pselect() System Call
The pselect() system call performs a similar task to select(). The main semantic differ-
ence is an additional argument, sigmask, that specifies a set of signals to be
unmasked while the call is blocked.
More precisely, suppose we have the following pselect() call:
ready = pselect(nfds, &readfds, &writefds, &exceptfds, timeout, &sigmask);
This call is equivalent to atomically performing the following steps:
sigset_t origmask;
sigprocmask(SIG_SETMASK, &sigmask, &origmask);
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL); /* Restore signal mask */
Using pselect(), we can recode the first part of the body of our main program in
Listing 63-7 as shown in Listing 63-8.
Aside from the sigmask argument, select() and pselect() differ in the following
ways:
z The timeout argument to pselect() is a timespec structure (Section 23.4.2), which
allows the timeout to be specified with nanosecond (instead of microsecond)
precision.
z SUSv3 explicitly states that pselect() doesn’t modify the timeout argument on return.
If we specify the sigmask argument of pselect() as NULL, then pselect() is equivalent to
select() (i.e., it performs no manipulation of the process signal mask), except for the
differences just noted.
The pselect() interface is an invention of POSIX.1g, and is nowadays incorpo-
rated in SUSv3. It is not available on all UNIX implementations, and was added to
Linux only in kernel 2.6.16.
Previously, a pselect() library function was provided by glibc, but this implemen-
tation didn’t provide the atomicity guarantees that are required for the correct
operation of the call. Such guarantees can be provided only by a kernel
implementation of pselect().
#define _XOPEN_SOURCE 600
#include <sys/select.h>
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timespec *timeout, const sigset_t *sigmask);
Returns number of ready file descriptors, 0 on timeout, or –1 on error