reality% num signal.c 1 /* signal.c 2 This program illustrate the use of the signal() system call. 3 Three child processes are created in this program. 4 In the first child, all signals are to be ignored except for SIGINT 5 and SIGALRM. Each is handled by a different signal handler. 6 After setting up the signals, this child process will go asleep to wait 7 for a signal to wake it up, and then go back to sleep again. 8 Note: Since it is an infinite loop, the child process will live forever 9 till it is terminated manually or system reboot. 10 In the second child, all signals are to be caught and handled by the same 11 signal handler. After setting up the signals, this child process will go 12 asleep waiting for a signal, and then this process will terminate after 13 the signal has been handled. 14 In the 3rd child, only SIGUSR2 will be caught. A new environment is setup 15 in this child, which will later be used in its predefined signal handler to 16 pass into a new program as its environment. 17 In the parent process, various signals are sent to these three child 18 processes. 19 */ 20 #include 21 #include 22 int pid; 23 static char *chdargv[] = {"cmd", "p1", (char *)0}; 24 static char *chdenv[4]; 25 main (int argc, char *argv[]) 26 { 27 int i, cpid1, cpid2, cpid3; 28 void wakeup(int), handler(int), trapper(int), parent(int); 29 if (!(cpid1 = fork())) { /* 1st child */ 30 pid = cpid1 = getpid(); /* get pid for child 1 */ 31 printf("\nCPID1 = %d", cpid1); 32 for (i = 1; i < NSIG; i++) 33 signal(i, SIG_IGN); /* ignore all signals (return status ignored) */ 34 signal(SIGINT, handler); /* except for interrupt */ 35 signal(SIGALRM, wakeup); /* and alarm clock */ 36 alarm((unsigned)2); /* set alarm for 2 secs */ 37 for (;;) 38 pause(); /* wait for signals */ 39 printf(" -- CPID1 (%d) terminates\n", cpid1); /* never gets here */ 40 exit(0); 41 } 42 else { 43 if (!(cpid2 = fork())) { /* 2nd child */ 44 pid = cpid2 = getpid(); /* get pid for child 2 */ 45 printf("\n\tCPID2 = %d", cpid2); 46 for (i = 1; i < NSIG; i++) 47 signal(i, trapper); /* to trap signals */ 48 pause(); 49 printf(" -- CPID2 (%d) terminates\n", cpid2); 50 exit(0); 51 } 52 else { 53 if (!(cpid3 = fork())) { /* 3rd child */ 54 pid = cpid3 = getpid(); /* get pid for child 3 */ 55 printf("\n\t\tCPID3 = %d ", cpid3); 56 signal(SIGUSR2, trapper); 57 chdenv[0] = "HOME=here"; 58 chdenv[1] = "PATH=/bin"; 59 chdenv[2] = "MAILX=/usr/lib/xxx"; 60 chdenv[3] = (char *)0 ; 61 pause(); 62 printf(" -- CPID3 (%d) terminates\n"); 63 exit(0); 64 } 65 /* parent process */ 66 pid = getpid(); /* pid for parent */ 67 sleep(3); /* to let child run first */ 68 printf("\nThis is parent process (pid = %d)\n", pid); 69 for (i = 1; i < NSIG; i++) 70 signal(i, parent); /* catch all signals */ 71 printf("\n\tSend SIGBUS(%d) to CPID1 (%d)", SIGBUS, cpid1); 72 kill(cpid1, SIGBUS); 73 printf("\n\tSend SIGINT(%d) to CPID1 (%d)", SIGINT, cpid1); 74 kill(cpid1, SIGINT); 75 printf("\n\t\tSend SIGBUS(%d) to CPID2 (%d)", SIGBUS, cpid2); 76 kill(cpid2, SIGBUS); 77 printf("\n\t\tSend SIGEMT(%d) to CPID2 (%d)", SIGEMT, cpid2); 78 kill(cpid2, SIGEMT); 79 printf("\n\t\tSend SIGUSR1(%d) to CPID2 (%d)", SIGUSR1, cpid2); 80 kill(cpid2, SIGUSR1); 81 printf("\n\t\t\tSend SIGUSR2(%d) to CPID3 (%d)", SIGUSR2, cpid3); 82 kill(cpid3, SIGUSR2); 83 wait((int *)0); 84 } 85 } 86 return(0); 87 } /* main */ 88 void wakeup(int dummy) 89 { 90 printf("\nI (pid = %d) am up now\n", pid); 91 } /* wakeup */ 92 void handler(int dummy) 93 { 94 printf("\nI (pid = %d) got an interrupt; will continue\n", pid); 95 } /* handler */ 96 void trapper(int i) 97 { 98 signal(i, trapper); /* old style; don't reset to default */ 99 if (i == SIGUSR1) { 100 printf("\n\tGot SIGUSR1(%d); process(%d) will terminate\n", i, pid); 101 exit(2); 102 } 103 else { 104 if (i == SIGUSR2) { 105 printf("\n\t\t(%d) got SIGUSR2(%d); execs a new program", i, pid); 106 execve("./sigexec", chdargv, chdenv); 107 perror("\nTHIS LINE SHOULDN'T BE HERE\n"); 108 } 109 else 110 printf("\n\tGot a signal(%d); process(%d) continues\n", i, pid); 111 } 112 } /* trapper */ 113 void parent(int sig) 114 { 115 printf("\nSignal (%d) received by parent (%d)", sig, pid); 116 } /* parent */ reality% num sigexec.c 1 /* sigexec.c 2 This program is used to print the commandline arguments' and current 3 environment variables' vaules. Note: It is called from signal.c 4 */ 5 extern char **environ; 6 main(int argc, char * argv[]) 7 { 8 char **env; 9 int i; 10 printf("\nParameters are:\n"); 11 for (i=0; i 18 #include 19 int pid; 20 static char *chdargv[] = {"cmd", "p1", (char *)0}; 21 static char *chdenv[4]; 22 main (int argc, char *argv[]) 23 { 24 int i, cpid1, cpid2, cpid3; 25 struct sigaction action, old_action; 26 void wakeup(), handler(), trapper(int), parent(int); 27 sigset_t sigmask; /* a process-wide signal mask */ 28 sigemptyset(&sigmask); /* to empty bits in sigmask */ 29 sigprocmask(SIG_SETMASK, &sigmask, 0); /* to initialize signal mask */ 30 action.sa_flags = 0; /* to init signal flags */ 31 action.sa_handler = SIG_IGN; /* to ignore signal */ 32 sigemptyset(&action.sa_mask); /* zero out sa_mask */ 33 if (!(cpid1 = fork())) { /* 1st child */ 34 pid = cpid1 = getpid(); /* get pid for child 1 */ 35 printf("\nCPID1 = %d", cpid1); 36 for (i = 1; i < NSIG; i++) 37 sigaction(i, &action, &old_action); /* ignore all signals */ 38 39 sigaddset(&action.sa_mask, SIGINT); /* add SIGINT to sa_mask ** 40 ** implicitly done, not needed, just for illustration purpose */ 41 action.sa_flags |= SA_RESTART; /* sys calls auto restart */ 42 action.sa_handler = handler; /* user-defined sig handler */ 43 sigaction(SIGINT, &action, &old_action); /* SIGINT is also blocked */ 44 sigaddset(&action.sa_mask, SIGALRM); /* again, for illustration */ 45 action.sa_handler = wakeup; /* another user-defined */ 46 sigaction(SIGALRM, &action, &old_action);/* SIGALRM is also blocked */ 47 alarm((unsigned)2); /* set alarm for 2 secs */ 48 for (;;) 49 pause(); /* wait for signals */ 50 printf(" -- CPID1 (%d) terminates\n", cpid2); /* never gets here */ 51 exit(0); 52 } 53 else { 54 if (!(cpid2 = fork())) { /* 2nd child */ 55 pid = cpid2 = getpid(); /* get pid for child 2 */ 56 printf("\n\tCPID2 = %d", cpid2); 57 action.sa_handler = trapper; /* one more user-defined */ 58 for (i = 1; i < NSIG; i++) 59 sigaction(i, &action, &old_action); 60 pause(); 61 printf(" -- CPID2 (%d) terminates\n", cpid2); 62 exit(0); 63 } 64 else { 65 if (!(cpid3 = fork())) { /* 3rd child */ 66 pid = cpid3 = getpid(); /* get pid for child 3 */ 67 printf("\n\t\tCPID3 = %d ", cpid3); 68 sigaddset(&action.sa_mask, SIGUSR2); /* block sig SIGUSR2 */ 69 action.sa_handler = trapper; 70 sigaction(SIGUSR2, &action, &old_action); 71 chdenv[0] = "HOME=here"; 72 chdenv[1] = "PATH=/bin"; 73 chdenv[2] = "MAILX=/usr/lib/xxx"; 74 chdenv[3] = (char *)0 ; 75 pause(); 76 printf(" -- CPID3 (%d) terminates\n"); 77 exit(0); 78 } 79 /* parent process */ 80 pid = getpid(); /* pid for parent */ 81 sleep(3); /* to let child run first 82 printf("\nThis is parent process (pid = %d)\n", pid); 83 sigfillset(&action.sa_mask); /* to block all signals */ 84 action.sa_handler = parent; /* all goes to parent */ 85 for (i = 1; i < NSIG; i++) 86 sigaction(i, &action, &old_action); /* catch all signals */ 87 printf("\n\tSend SIGBUS(%d) to CPID1 (%d)", SIGBUS, cpid1); 88 kill(cpid1, SIGBUS); 89 printf("\n\tSend SIGINT(%d) to CPID1 (%d)", SIGINT, cpid1); 90 kill(cpid1, SIGINT); 91 printf("\n\t\tSend SIGBUS(%d) to CPID2 (%d)", SIGBUS, cpid2); 92 kill(cpid2, SIGBUS); 93 printf("\n\t\tSend SIGEMT(%d) to CPID2 (%d)", SIGEMT, cpid2); 94 kill(cpid2, SIGEMT); 95 printf("\n\t\tSend SIGUSR1(%d) to CPID2 (%d)", SIGUSR1, cpid2); 96 kill(cpid2, SIGUSR1); 97 printf("\n\t\t\tSend SIGUSR2(%d) to CPID3 (%d)", SIGUSR1, cpid3); 98 kill(cpid3, SIGUSR2); 99 wait((int *)0); 100 } 101 } 102 return(0); 103 } /* main */ 104 void wakeup() 105 { 106 printf("\nI (pid = %d) am up now\n", pid); 107 } /* wakeup */ 108 void handler() 109 { 110 printf("\nI (pid = %d) got an interrupt; will continue\n", pid); 111 } /* handler */ 112 void trapper(int i) 113 { 114 /* No reset is needed any more */ 115 if (i == SIGUSR1) { 116 printf("\n\tGot SIGUSR1(%d); process(%d) will terminate\n", i, pid); 117 exit(2); 118 } 119 else { 120 if (i == SIGUSR2) { 121 printf("\n\t\t(%d) got SIGUSR2(%d); execs a new program", i, pid); 122 execve("./sigexec", chdargv, chdenv); 123 perror("\nTHIS LINE SHOULDN'T BE HERE\n"); 124 } 125 else 126 printf("\n\tGot a signal(%d); process(%d) continues\n", i, pid); 127 } 128 } /* trapper */ 129 void parent(int sig) 130 { 131 printf("\nSignal (%d) received by parent (%d)", sig, pid); 132 } /* parent */