[PATCH] pselect: Use linux pselect syscall when available
Nic Dade
nic.dade at gmail.com
Sat Dec 19 03:28:43 UTC 2015
> real code / testcase
Should be easy.... yup. With an unpatched uclibc this code hangs in
pselect() because the pending signal fires during the window between the
sigprocmkas() and the select(). A proper pselect() returns with errno EINTR.
---------------------------------------------------------------------------------------------
#define _GNU_SOURCE // gimme the good stuff
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/select.h>
// our SIGALRM handler
void handler(int signum) {
(void)signum;
write(1, "got signal\n", 11);
}
int main(int argc, char** argv) {
(void)argc;
(void)argv;
// block SIGALRM. We want to handle it only when we're ready
sigset_t wait_mask, mask_sigchld;
sigemptyset(&mask_sigchld);
sigaddset(&mask_sigchld, SIGALRM);
sigprocmask(SIG_BLOCK, &mask_sigchld, &wait_mask);
sigdelset(&wait_mask, SIGALRM);
// register a signal handler so we can see when the signal arrives
struct sigaction act;
memset(&act, 0, sizeof(act));
sigemptyset(&act.sa_mask); // just in case an empty set isn't all
0's (total paranoia)
act.sa_handler = handler;
sigaction(SIGALRM, &act, NULL);
// send ourselves a SIGARLM. It will pend until we unblock that
signal in pselect()
printf("sending ourselves a signal\n");
kill(getpid(), SIGALRM);
printf("signal is pending; calling pselect()\n");
int rc = pselect(0, NULL, NULL, NULL, NULL, &wait_mask);
int e = errno;
printf("pselect() returned %d, errno %d (%s)\n", rc, e,
strerror(e));
return 0;
}
On Fri, Dec 18, 2015 at 10:37 AM, Rich Felker <dalias at libc.org> wrote:
> On Thu, Dec 17, 2015 at 09:05:48PM +0100, Waldemar Brodkorb wrote:
> > Hi Nicolas,
> > Nicolas S. Dade wrote,
> >
> > > Linux has a pselect syscall since 2.6.something. Using it
> > > rather than emulating it with sigprocmask+select+sigprocmask
> > > is smaller code, and works properly. (The emulation has
> > > race conditions when unblocked signals arrive before or
> > > after the select)
> >
> > Did you see the race condition in real code or do you have
> > a testcase for it?
>
> The race conditions should be easy to reproduce since you have a
> relatively huge syscall-latency-length (several us) window to race
> with. Fake pselect implementations are historically known to be
> harmful; the whole reason pselect was invented was to fix these races
> in old code that used sigprocmask followed by select.
>
> Rich
>
More information about the uClibc
mailing list