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