1 #include <sys/types.h> 2 #include <sys/wait.h> 3 #include <err.h> 4 #include <errno.h> 5 #include <signal.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 10 int stop_received; 11 int exit_received; 12 int cont_received; 13 14 void 15 job_handler(int sig, siginfo_t *si, void *ctx) 16 { 17 int status; 18 int ret; 19 20 if (si->si_code == CLD_STOPPED) { 21 printf("%d: stop received\n", si->si_pid); 22 stop_received = 1; 23 kill(si->si_pid, SIGCONT); 24 } else if (si->si_code == CLD_EXITED) { 25 printf("%d: exit received\n", si->si_pid); 26 ret = waitpid(si->si_pid, &status, 0); 27 if (ret == -1) 28 errx(1, "waitpid"); 29 if (!WIFEXITED(status)) 30 errx(1, "!WIFEXITED(status)"); 31 exit_received = 1; 32 } else if (si->si_code == CLD_CONTINUED) { 33 printf("%d: cont received\n", si->si_pid); 34 cont_received = 1; 35 } 36 } 37 38 void 39 job_control_test(void) 40 { 41 struct sigaction sa; 42 pid_t pid; 43 int count = 10; 44 45 sigemptyset(&sa.sa_mask); 46 sa.sa_flags = SA_SIGINFO; 47 sa.sa_sigaction = job_handler; 48 sigaction(SIGCHLD, &sa, NULL); 49 stop_received = 0; 50 cont_received = 0; 51 exit_received = 0; 52 fflush(stdout); 53 pid = fork(); 54 if (pid == 0) { 55 printf("child %d\n", getpid()); 56 kill(getpid(), SIGSTOP); 57 sleep(2); 58 exit(1); 59 } 60 61 while (!(cont_received && stop_received && exit_received)) { 62 sleep(1); 63 if (--count == 0) 64 break; 65 } 66 if (!(cont_received && stop_received && exit_received)) 67 errx(1, "job signals lost"); 68 69 printf("job control test OK.\n"); 70 } 71 72 void 73 rtsig_handler(int sig, siginfo_t *si, void *ctx) 74 { 75 } 76 77 int 78 main() 79 { 80 struct sigaction sa; 81 sigset_t set; 82 union sigval val; 83 84 /* test job control with empty signal queue */ 85 job_control_test(); 86 87 /* now full fill signal queue in kernel */ 88 sigemptyset(&sa.sa_mask); 89 sa.sa_flags = SA_SIGINFO; 90 sa.sa_sigaction = rtsig_handler; 91 sigaction(SIGRTMIN, &sa, NULL); 92 sigemptyset(&set); 93 sigaddset(&set, SIGRTMIN); 94 sigprocmask(SIG_BLOCK, &set, NULL); 95 val.sival_int = 1; 96 while (sigqueue(getpid(), SIGRTMIN, val)) 97 ; 98 99 /* signal queue is fully filled, test the job control again. */ 100 job_control_test(); 101 return (0); 102 } 103