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