From: David Laight > Sent: 11 June 2019 10:52 ... > If I have an application that has a loop with a pselect call that > enables SIGINT (without a handler) and, for whatever reason, > one of the fd is always 'ready' then I'd expect a SIGINT > (from ^C) to terminate the program. > > A quick test program: > > #include <sys/time.h> > #include <sys/types.h> > #include <unistd.h> > > #include <sys/select.h> > #include <signal.h> > > int main(int argc, char **argv) > { > fd_set readfds; > sigset_t sig_int; > struct timespec delay = {1, 0}; > > sigfillset(&sig_int); > sigdelset(&sig_int, SIGINT); > > sighold(SIGINT); > > for (;;) { > FD_ZERO(&readfds); > FD_SET(0, &readfds); > pselect(1, &readfds, NULL, NULL, &delay, &sig_int); > > poll(0,0,1000); > } > } > > Run under strace to see what is happening and send SIGINT from a different > terminal. > The program sleeps for a second in each of the pselect() and poll() calls. > Send a SIGINT and in terminates after pselect() returns ERESTARTNOHAND. > > Run again, this time press enter - making fd 0 readable. > pselect() returns 1, but the program still exits. > (Tested on a 5.1.0-rc5 kernel.) > > If a signal handler were defined it should be called instead.
If I add a signal handler for SIGINT it is called when pselect() returns regardless of the return value. If I setup SIGUSR1/2 the same way as SIGINT and get the SIGINT handler to sighold() and then raise both of them, the USR1/2 handlers are both called on the next pselect() call. (Without the extra sighold() the handlers are called when kill() returns.) I'd expect the epoll functions to work the same way. sigtimedwait is different though - it returns the number of the pending signal (and doesn't call the handler). So if two signals are pending neither handler should be called. The second signal would be returned on the following sigtimedwait call. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)