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