#include #include #include #include #include #include #include #include #include void catch_hup(int sig) { printf("HUP\n"); } void catch_int(int sig) { printf("INT\n"); } void catch_quit(int sig) { printf("QUIT\n"); } void catch_ill(int sig) { printf("ILL\n"); } void catch_trap(int sig) { printf("TRAP\n"); } void catch_abrt(int sig) { printf("ABRT\n"); } void catch_bus(int sig) { printf("BUS\n"); } void catch_fpe(int sig) { printf("FPE\n"); } void catch_kill(int sig) { printf("KILL\n"); } void catch_usr1(int sig) { printf("USR1\n"); } void catch_segv(int sig) { printf("SEGV\n"); } void catch_usr2(int sig) { printf("USR2\n"); } void catch_pipe(int sig) { printf("PIPE\n"); } void catch_alarm(int sig) { printf("ALARM\n"); } void catch_term(int sig) { printf("TERM\n"); } void catch_stkflt(int sig) { printf("STKFLT\n"); } void catch_chld(int sig) { printf("CHLD\n"); } void catch_cont(int sig) { printf("CONT\n"); } void catch_stop(int sig) { printf("STOP\n"); } void catch_stp(int sig) { printf("STP\n"); } void catch_ttin(int sig) { printf("TTIN\n"); } void catch_ttou(int sig) { printf("TTOU\n"); } void catch_urg(int sig) { printf("URG\n"); } void catch_xcpu(int sig) { printf("XCPU\n"); } void catch_xfsz(int sig) { printf("XFSZ\n"); } void catch_vtalrm(int sig) { printf("VTALRM\n"); } void catch_prof(int sig) { printf("PROF\n"); } void catch_winch(int sig) { printf("WINCH\n"); } void catch_gio(int sig) { printf("GIO\n"); } void catch_pwr(int sig) { printf("PWR\n"); } void catch_sys(int sig) { printf("SYS\n"); } static const char *handler_names[] = { "zero has no handler", "hup", "int", "quit", "ill", "trap", "abrt", "bus", "fpe", "kill", "usr1", "segv", "usr2", "pipe", "alarm", "term", "stkflt", "chld", "cont", "stop", "stp", "ttin", "ttou", "urg", "xcpu", "xfsz", "vtalrm", "prof", "winch", "gio", "pwr", "sys", }; static void (*handler_table[])(int) = { NULL, catch_hup, //SIGHUP catch_int, //SIGINT catch_quit, //SIGQUIT catch_ill, //SIGILL catch_trap, //SIGTRAP catch_abrt, //SIGABRT catch_bus, //SIGBUS catch_fpe, //SIGFPE catch_kill, //SIGKILL catch_usr1, //SIGUSR1 catch_segv, //SIGSEGV catch_usr2, //SIGUSR2 catch_pipe, //SIGPIPE catch_alarm,//SIGALRM catch_term, //SIGTERM catch_stkflt,//SIGSTKFLT catch_chld, //SIGCHLD catch_cont, //SIGCONT catch_stop, //SIGSTOP catch_stp, //SIGTSTP catch_ttin, //SIGTTIN catch_ttou, //SIGTTOU catch_urg, //SIGURG catch_xcpu, //SIGXCPU catch_xfsz, //SIGXFSZ catch_vtalrm,//SIGVTALRM catch_prof, //SIGPROF catch_winch,//SIGWINCH catch_gio, //SIGIO catch_pwr, //SIGPWR catch_sys, //SIGSYS }; int main(int argc, const char *argv[]) { pid_t child; int status; int sig; unsigned self = 0; size_t n_handlers = sizeof(handler_names) / sizeof(handler_names[0]); if (argc <= 1) { printf("Usage: xxx [self]\n"); exit(1); } if (argc == 3) self = 1; for (sig = 0; sig < n_handlers; sig++) { if (strcmp(argv[1], handler_names[sig]) == 0) break; } if (sig == n_handlers) { printf("Unknown handler %s\n", argv[1]); exit(1); } if (self) { // Test actual crashes / panics if (sig != SIGABRT && sig != SIGSEGV) signal(sig, handler_table[sig]); kill(getpid(), sig); return 0; } child = fork(); if (child < 0) { fprintf(stderr, "fork failed!\n"); return -1; } if (child == 0) { signal(sig, handler_table[sig]); sleep(2); return 0; } else { // Parent sleep(1); kill(child, sig); } wait(&status); return 0; }