00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include <pthread.h>
00023
00024
00025 static void clean_up(void)
00026 {
00027
00028
00029
00030
00031 }
00032
00033
00034
00035
00036 static void *sig_thread(void *arg)
00037 {
00038 int signum;
00039 int i;
00040 struct {
00041 int signum;
00042 char *msg;
00043 } sigmsg[] = {
00044 { SIGTERM, "Termination signal" },
00045 { SIGBUS, "Access to undefined portion of a memory object" },
00046 { SIGFPE, "Erroneous arithmetic operation" },
00047 { SIGILL, "Illegal instruction" },
00048 { SIGSEGV, "Invalid memory reference" },
00049 { SIGSYS, "Bad system call" },
00050 { SIGXCPU, "CPU-time limit exceeded" },
00051 { SIGXFSZ, "File-size limit exceeded" },
00052 { 0, NULL}
00053 };
00054
00055 {
00056 int x = 1, y;
00057
00058 printf("about to divide by zero\n");
00059 y = x / 0;
00060 }
00061 printf("still alive\n");
00062 while (true) {
00063 ec_rv( sigwait((sigset_t *)arg, &signum) )
00064 clean_up();
00065 for (i = 0; sigmsg[i].signum > 0; i++)
00066 if (sigmsg[i].signum == signum) {
00067 fprintf(stderr, "%s\n", sigmsg[i].msg);
00068 break;
00069 }
00070 _exit(EXIT_FAILURE);
00071 }
00072 return (void *)true;
00073
00074 EC_CLEANUP_BGN
00075 EC_FLUSH("sig_thread")
00076 return (void *)false;
00077 EC_CLEANUP_END
00078 }
00079
00080 static void handler(int signum)
00081 {
00082 printf("got %d in handler\n", signum);
00083 }
00084
00085 static bool handle_signals(void)
00086 {
00087 sigset_t *set;
00088 struct sigaction act;
00089 pthread_t tid;
00090
00091 ec_null( set = malloc(sizeof(*set)) )
00092 ec_neg1( sigfillset(set) )
00093 ec_rv( pthread_sigmask(SIG_SETMASK, set, NULL) )
00094 memset(&act, 0, sizeof(act));
00095 act.sa_handler = SIG_IGN;
00096 ec_neg1( sigaction(SIGHUP, &act, NULL) )
00097 ec_neg1( sigaction(SIGINT, &act, NULL) )
00098 ec_neg1( sigaction(SIGQUIT, &act, NULL) )
00099 ec_neg1( sigaction(SIGPIPE, &act, NULL) )
00100 ec_neg1( sigemptyset(set) )
00101 ec_neg1( sigaddset(set, SIGTERM) )
00102 ec_neg1( sigaddset(set, SIGBUS) )
00103 ec_neg1( sigaddset(set, SIGFPE) )
00104 ec_neg1( sigaddset(set, SIGILL) )
00105 ec_neg1( sigaddset(set, SIGSEGV) )
00106 ec_neg1( sigaddset(set, SIGSYS) )
00107 ec_neg1( sigaddset(set, SIGXCPU) )
00108 ec_neg1( sigaddset(set, SIGXFSZ) )
00109 ec_rv( pthread_sigmask(SIG_SETMASK, set, NULL) )
00110 ec_rv( pthread_create(&tid, NULL, sig_thread, set) )
00111 return true;
00112
00113 EC_CLEANUP_BGN
00114 return false;
00115 EC_CLEANUP_END
00116 }
00117
00118 void process(void)
00119 {
00120 ec_false (handle_signals() )
00121 sleep(2);
00122 {
00123 int x = 1, y;
00124
00125
00126 }
00127 exit(EXIT_SUCCESS);
00128
00129 EC_CLEANUP_BGN
00130 exit(EXIT_FAILURE);
00131 EC_CLEANUP_END
00132 }
00133
00134 #define MAX_SIG 50
00135
00136 int main(void)
00137 {
00138 int signum;
00139 pid_t pid[MAX_SIG + 1];
00140 int status;
00141
00142 for (signum = 1; signum <= MAX_SIG; signum++) {
00143 ec_neg1( pid[signum] = fork() )
00144 if (pid[signum] == 0)
00145 process();
00146 sleep(1);
00147 printf("\nSending signal %d...\n", signum);
00148
00149
00150 ec_neg1( waitpid(-1, &status, WUNTRACED) )
00151 if (WIFEXITED(status))
00152 printf("%ld exited normally\n", (long)pid[signum]);
00153 else if (WIFSIGNALED(status))
00154 printf("%ld exited with signal %d\n", (long)pid[signum],
00155 WTERMSIG(status));
00156 else
00157 printf("wait returned with other status\n");
00158 }
00159 for (signum = 1; signum <= MAX_SIG; signum++)
00160 (void)kill(pid[signum], SIGKILL);
00161 exit(EXIT_SUCCESS);
00162
00163 EC_CLEANUP_BGN
00164 exit(EXIT_FAILURE);
00165 EC_CLEANUP_END
00166 }
00167