| #include <unistd.h> |
| #include <signal.h> |
| #include <errno.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <sys/wait.h> |
| #include <sys/types.h> |
| #include <stdlib.h> |
| |
| static void do_exec(const char *path, const char *arg, const sigset_t *mask) |
| { |
| pid_t pid; |
| int status; |
| |
| pid = fork(); |
| if (pid == -1) { |
| perror("fork"); |
| exit(1); |
| } |
| if (pid == 0) { |
| sigprocmask(SIG_SETMASK, mask, NULL); |
| execl(path, path, arg, NULL); |
| |
| fprintf(stderr, "FAILED: execl failed with %s\n", |
| strerror(errno)); |
| } else { |
| int ret; |
| do |
| ret = waitpid(pid, &status, 0); |
| while(ret == -1 && errno == EINTR); |
| if (ret != pid) { |
| perror("waitpid"); |
| exit(1); |
| } |
| if (status != 0) { |
| fprintf(stderr, "child exec failed\n"); |
| exit(1); |
| } |
| } |
| } |
| |
| int main(int argc, char **argv) |
| { |
| if (argc == 1) { |
| sigset_t mask; |
| |
| sigfillset(&mask); |
| do_exec(argv[0], "full", &mask); |
| |
| sigemptyset(&mask); |
| do_exec(argv[0], "empty", &mask); |
| } else { |
| sigset_t mask; |
| int i; |
| int empty; |
| |
| if (strcmp(argv[1], "full") == 0) |
| empty = 0; |
| else if (strcmp(argv[1], "empty") == 0) |
| empty = 1; |
| else { |
| fprintf(stderr, "empty or full?\n"); |
| exit(1); |
| } |
| |
| sigprocmask(SIG_SETMASK, NULL, &mask); |
| |
| for(i = 1; i < NSIG; i++) { |
| if (i == SIGKILL || i == SIGSTOP) |
| continue; |
| |
| if (empty) { |
| if (sigismember(&mask, i)) |
| printf("empty: signal %d added to mask\n", i); |
| } else { |
| if (!sigismember(&mask, i)) |
| printf("full: signal %d missing from mask\n", i); |
| } |
| } |
| } |
| |
| return 0; |
| } |