TOC   Previous   Next

pselect(2)

Why

Problem: how to safely wait for a file descriptor or a signal?

The problem is that the following code has a race:

sig_atomic_t gotSig = 0;   /* Global flag */

void
handler(int sig)
{
    gotSig = 1;            /* Tell main() we got a signal */
} /* handler */

int
main(int argc, char *argv[])
{
    struct sigaction sa;
    ...

    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGUSR1, &sa, NULL);

    ...

    /* What if the signal is delivered now? */

    ready = select(nfds, &readfds, NULL, NULL, NULL);
	
    if (ready > 0) {
        printf("%d file descriptors ready\n", ready);
		
    } else if (ready == -1 && errno == EINTR) {
        if (gotSig)
            printf("Got signal\n");
    } else {
        /* Some other error */
    }

First signal might arrive before select(): if so, select() only returns after a second signal arrives.

Even blocking the signal (sigprocmask(2)) until just before the select() call does not eliminate the race.


(C) 2006, Michael Kerrisk