#define _GNU_SOURCE #include #include #include #include #if 0 /* The sigprocmask syscall works correctly */ _syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset); #else /* The rt_sigprocmask syscall currently fails */ _syscall4(int, rt_sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset, size_t, size); int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { return rt_sigprocmask(how, set, oldset, _NSIG/8); } #endif int main(void) { sigset_t set; sigset_t oset; int r; sigemptyset(&set); sigemptyset(&oset); /* Block no signals since set is empty. * oset will be set to the app default. */ errno = 0; r = sigprocmask(SIG_SETMASK, &set, &oset); if (r != 0) { printf("r=%d : %m\n", r); } /* Block no signals since set is empty. * oset will now also be empty. */ errno = 0; r = sigprocmask(SIG_SETMASK, &set, &oset); if (r != 0) { printf("r=%d : %m\n", r); } /* * SuSv3 says: * "The * argument how indicates the way in which the set is * changed, and the application shall ensure it consists of one * of [SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK] ... If sigprocmask() * fails, the thread's signal mask shall not be changed." * * Attempt to block SIGHUP with a bogus 'how'. This should fail, * and return EINVAL, and oset should should still be empty. */ errno = 0; r = sigaddset(&set, SIGHUP); if (r != 0) { printf("r=%d : %m\n", r); } errno = 0; r = sigprocmask(0xdeadbeef, &set, &oset); if (r != 0) { printf("Expected failure: %m\n"); } /* Query the value of oset. It should still be empty */ errno = 0; r = sigprocmask(SIG_SETMASK, (sigset_t *)0, &oset); if (r != 0) { printf("r=%d : %m\n", r); } /* But oset is not empty! This is contrary to SuSv3! */ if (sigismember(&oset, SIGHUP)==1) { printf("FAIL -- oset was changed when we supplied an invalid 'how'\n"); return 1; } else { printf("PASS\n"); } return 0; }