1 // RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s 2 3 // sigandset is glibc specific. 4 // UNSUPPORTED: android, freebsd, netbsd 5 6 #include <assert.h> 7 #include <signal.h> 8 #include <stdio.h> 9 #include <sys/time.h> 10 #include <sys/wait.h> 11 #include <unistd.h> 12 13 sigset_t mkset(int n, ...) { 14 sigset_t s; 15 int res = 0; 16 res |= sigemptyset(&s); 17 va_list va; 18 va_start(va, n); 19 while (n--) { 20 res |= sigaddset(&s, va_arg(va, int)); 21 } 22 va_end(va); 23 assert(!res); 24 return s; 25 } 26 27 sigset_t sigset_or(sigset_t first, sigset_t second) { 28 sigset_t out; 29 int res = sigorset(&out, &first, &second); 30 assert(!res); 31 return out; 32 } 33 34 sigset_t sigset_and(sigset_t first, sigset_t second) { 35 sigset_t out; 36 int res = sigandset(&out, &first, &second); 37 assert(!res); 38 return out; 39 } 40 41 int fork_and_signal(sigset_t s) { 42 if (pid_t pid = fork()) { 43 kill(pid, SIGUSR1); 44 kill(pid, SIGUSR2); 45 int child_stat; 46 wait(&child_stat); 47 return !WIFEXITED(child_stat); 48 } else { 49 int sig; 50 int res = sigwait(&s, &sig); 51 assert(!res); 52 fprintf(stderr, "died with sig %d\n", sig); 53 _exit(0); 54 } 55 } 56 57 void test_sigwait() { 58 // test sigorset... s should now contain SIGUSR1 | SIGUSR2 59 sigset_t s = sigset_or(mkset(1, SIGUSR1), mkset(1, SIGUSR2)); 60 sigprocmask(SIG_BLOCK, &s, 0); 61 int res; 62 res = fork_and_signal(s); 63 fprintf(stderr, "fork_and_signal with SIGUSR1,2: %d\n", res); 64 // CHECK: died with sig 10 65 // CHECK: fork_and_signal with SIGUSR1,2: 0 66 67 // test sigandset... s should only have SIGUSR2 now 68 s = sigset_and(s, mkset(1, SIGUSR2)); 69 res = fork_and_signal(s); 70 fprintf(stderr, "fork_and_signal with SIGUSR2: %d\n", res); 71 // CHECK: died with sig 12 72 // CHECK: fork_and_signal with SIGUSR2: 0 73 } 74 75 int main(void) { 76 test_sigwait(); 77 return 0; 78 } 79