1 #include <unistd.h> 2 #include <signal.h> 3 #include <errno.h> 4 #include <string.h> 5 #include <stdio.h> 6 #include <sys/wait.h> 7 #include <sys/types.h> 8 #include <stdlib.h> 9 10 static void do_exec(const char *path, const char *arg, const sigset_t *mask) 11 { 12 pid_t pid; 13 int status; 14 15 pid = fork(); 16 if (pid == -1) { 17 perror("fork"); 18 exit(1); 19 } 20 if (pid == 0) { 21 sigprocmask(SIG_SETMASK, mask, NULL); 22 execl(path, path, arg, NULL); 23 24 fprintf(stderr, "FAILED: execl failed with %s\n", 25 strerror(errno)); 26 } else { 27 int ret; 28 do 29 ret = waitpid(pid, &status, 0); 30 while(ret == -1 && errno == EINTR); 31 if (ret != pid) { 32 perror("waitpid"); 33 exit(1); 34 } 35 if (status != 0) { 36 fprintf(stderr, "child exec failed\n"); 37 exit(1); 38 } 39 } 40 } 41 42 int main(int argc, char **argv) 43 { 44 if (argc == 1) { 45 sigset_t mask; 46 47 sigfillset(&mask); 48 do_exec(argv[0], "full", &mask); 49 50 sigemptyset(&mask); 51 do_exec(argv[0], "empty", &mask); 52 } else { 53 sigset_t mask; 54 int i; 55 int empty; 56 57 if (strcmp(argv[1], "full") == 0) 58 empty = 0; 59 else if (strcmp(argv[1], "empty") == 0) 60 empty = 1; 61 else { 62 fprintf(stderr, "empty or full?\n"); 63 exit(1); 64 } 65 66 sigprocmask(SIG_SETMASK, NULL, &mask); 67 68 for(i = 1; i < NSIG; i++) { 69 if (i == SIGKILL || i == SIGSTOP) 70 continue; 71 72 if (empty) { 73 if (sigismember(&mask, i)) 74 printf("empty: signal %d added to mask\n", i); 75 } else { 76 if (!sigismember(&mask, i)) 77 printf("full: signal %d missing from mask\n", i); 78 } 79 } 80 } 81 82 return 0; 83 } 84