1: /* 2: * $Id: catch.c,v 1.20 2006/05/31 10:35:38 yamamoto Exp yamamoto $ 3: */ 4: 5: #include <signal.h> /* For sigaction(). */ 6: #include <stdarg.h> /* For variable argument lists. */ 7: #include <stdio.h> 8: #include <stdlib.h> /* For EXIT_SUCCESS. */ 9: 10: #define MAX_LINE_LEN 81 11: 12: #ifndef FALSE 13: #define FALSE 0 14: #define TRUE 1 15: #endif 16: 17: static int debug_mode = FALSE; 18: 19: static void set_signal_handler(void); 20: 21: static void debug(const char *format, ...); 22: static void handler(int x); 23: 24: int main(int argc, char *argv[]) 25: { 26: char input[MAX_LINE_LEN]; 27: int status; 28: pid_t pid; 29: 30: if (2 <= argc && !strcmp(argv[1], "-d")) { 31: debug_mode = TRUE; 32: } 33: set_signal_handler(); /* シグナルハンドラの登録. */ 34: 35: /* 意図的にSIGSEGVを起こす. */ 36: /* { char *cp = NULL; *cp = '\0'; } */ 37: 38: debug("catch: getpid() %d.\n", getpid()); 39: while (1) { 40: fprintf(stderr, "catch: Zzz.\n"); 41: sleep(1); 42: } 43: 44: exit (EXIT_SUCCESS); 45: } 46: 47: /* 48: * シグナルハンドラを設定する. 49: */ 50: 51: static void set_signal_handler(void) 52: { 53: static struct sigaction action; 54: 55: action.sa_handler = handler; /* シグナルハンドラ. */ 56: 57: /* ハンドラ内でSIGINTをブロックする. */ 58: sigemptyset(&action.sa_mask); /* マスクのクリア. */ 59: sigaddset(&action.sa_mask, SIGINT); 60: 61: action.sa_flags = SA_RESTART; /* BSDとの互換性(おまじない). */ 62: 63: /* 実験: シグナルハンドラが一度呼ばれると設定をクリアする. */ 64: /* action.sa_flags = action.sa_flags | SA_ONESHOT; */ 65: 66: sigaction(SIGINT, &action, NULL); /* SIGINTにハンドラを設定.*/ 67: sigaction(SIGSEGV, &action, NULL); /* SIGSEGVにも設定.*/ 68: sigaction(SIGUSR1, &action, NULL); /* SIGUSR1にも設定. */ 69: sigaction(SIGCONT, &action, NULL); /* SIGCONTにも設定. */ 70: } 71: 72: /* 73: * シグナルハンドラ. 74: */ 75: 76: static void handler(int x) 77: { 78: char *sig_name; 79: 80: fflush(stdout); 81: fflush(stderr); 82: 83: /* !! Not so good. */ 84: if (x == SIGINT) { 85: sig_name = "SIGINT"; 86: } else if (x == SIGSEGV) { 87: sig_name = "SIGSEGV"; 88: } else if (x == SIGUSR1) { 89: sig_name = "SIGUSR1"; 90: } else if (x == SIGCONT) { 91: sig_name = "SIGCONT"; 92: } else { 93: sig_name = "UNKNOWN"; 94: } 95: fprintf(stderr, "catch: Signal (%s, %d).\n", sig_name, x); 96: 97: if (x == SIGSEGV) { 98: exit (EXIT_FAILURE); 99: } 100: } 101: 102: static void debug(const char *format, ...) 103: { 104: va_list args; 105: 106: if (!debug_mode) { 107: return; 108: } 109: 110: fflush(stdout); 111: fflush(stderr); 112: 113: fputs("Debug: ", stderr); 114: va_start(args, format); 115: vfprintf(stderr, format, args); 116: va_end(args); 117: 118: fflush(stderr); 119: }