/* * ep - extended pipelining * * sigserv.c - signal handling * ____________________________________________________________ * * Developed by Ondrej Jombik * and Lubomir Host * Copyright (c) 2000-2003 Platon SDG, http://platon.sk/ * All rights reserved. * * See README file for more information about this software. * See COPYING file for license information. * * Download the latest version from * http://platon.sk/projects/ep/ */ /* $Platon: ep/src/sigserv.c,v 1.13 2003/05/03 09:58:19 nepto Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #ifdef STDC_HEADERS # include # include #endif #if HAVE_UNISTD_H # include # include #endif #if HAVE_SYS_WAIT_H # include #endif #include "sigserv.h" #include "message.h" #if DEBUG static char *get_signal_str(int sig_no) { char *s; switch (sig_no) { default: s = "unknown"; break; case SIGHUP: s = "SIGHUP"; break; case SIGINT: s = "SIGINT"; break; case SIGQUIT: s = "SIGQUIT"; break; case SIGILL: s = "SIGILL"; break; case SIGTRAP: s = "SIGTRAP"; break; case SIGABRT: s = "SIGABRT"; break; /* case SIGIOT: s = "SIGIOT"; break; */ case SIGBUS: s = "SIGBUS"; break; case SIGFPE: s = "SIGFPE"; break; case SIGKILL: s = "SIGKILL"; break; case SIGUSR1: s = "SIGUSR1"; break; case SIGSEGV: s = "SIGSEGV"; break; case SIGUSR2: s = "SIGUSR2"; break; case SIGPIPE: s = "SIGPIPE"; break; case SIGALRM: s = "SIGALRM"; break; case SIGTERM: s = "SIGTERM"; break; case SIGSTKFLT: s = "SIGSTKFLT"; break; /* case SIGCLD: s = "SIGCLD"; break; */ case SIGCHLD: s = "SIGCHLD"; break; case SIGCONT: s = "SIGCONT"; break; case SIGSTOP: s = "SIGSTOP"; break; case SIGTSTP: s = "SIGTSTP"; break; case SIGTTIN: s = "SIGTTIN"; break; case SIGTTOU: s = "SIGTTOU"; break; case SIGURG: s = "SIGURG"; break; case SIGXCPU: s = "SIGXCPU"; break; case SIGXFSZ: s = "SIGXFSZ"; break; case SIGVTALRM: s = "SIGVTALRM"; break; case SIGPROF: s = "SIGPROF"; break; case SIGWINCH: s = "SIGWINCH"; break; case SIGPOLL: s = "SIGPOLL"; break; /* case SIGIO: s = "SIGIO"; break; */ case SIGPWR: s = "SIGPWR"; break; case SIGSYS: s = "SIGSYS"; break; } return s; } static char *get_signal_description(int sig_no) { char *s; switch (sig_no) { default: s = "unknown"; break; case SIGHUP: s = "Hangup (POSIX)"; break; case SIGINT: s = "Interrupt (ANSI)"; break; case SIGQUIT: s = "Quit (POSIX)"; break; case SIGILL: s = "Illegal instruction (ANSI)"; break; case SIGTRAP: s = "Trace trap (POSIX)"; break; case SIGABRT: s = "Abort (ANSI)"; break; /* case SIGIOT: s = "IOT trap (4.2 BSD)"; break; */ case SIGBUS: s = "BUS error (4.2 BSD)"; break; case SIGFPE: s = "Floating-point exception (ANSI)"; break; case SIGKILL: s = "Kill, unblockable (POSIX)"; break; case SIGUSR1: s = "User-defined signal 1 (POSIX)"; break; case SIGSEGV: s = "Segmentation violation (ANSI)"; break; case SIGUSR2: s = "User-defined signal 2 (POSIX)"; break; case SIGPIPE: s = "Broken pipe (POSIX)"; break; case SIGALRM: s = "Alarm clock (POSIX)"; break; case SIGTERM: s = "Termination (ANSI)"; break; case SIGSTKFLT: s = "Stack fault"; break; /* case SIGCLD: s = "Same as SIGCHLD (System V)"; break; */ case SIGCHLD: s = "Child status has changed (POSIX)"; break; case SIGCONT: s = "Continue (POSIX)"; break; case SIGSTOP: s = "Stop, unblockable (POSIX)"; break; case SIGTSTP: s = "Keyboard stop (POSIX)"; break; case SIGTTIN: s = "Background read from tty (POSIX)"; break; case SIGTTOU: s = "Background write to tty (POSIX)"; break; case SIGURG: s = "Urgent condition on socket (4.2 BSD)"; break; case SIGXCPU: s = "CPU limit exceeded (4.2 BSD)"; break; case SIGXFSZ: s = "File size limit exceeded (4.2 BSD)"; break; case SIGVTALRM: s = "Virtual alarm clock (4.2 BSD)"; break; case SIGPROF: s = "Profiling alarm clock (4.2 BSD)"; break; case SIGWINCH: s = "Window size change (4.3 BSD, Sun)"; break; case SIGPOLL: s = "Pollable event occurred (System V)"; break; /* case SIGIO: s = "I/O now possible (4.2 BSD)"; break; */ case SIGPWR: s = "Power failure restart (System V)"; break; case SIGSYS: s = "Bad system call"; break; }; return s; } #endif static RETSIGTYPE sigserv_sigaction(sig, info, unused) int sig; siginfo_t *info; void *unused; { #if DEBUG msg_debug_print("sigserv_sigaction(): sig = %s [%s]\n", get_signal_str(sig), get_signal_description(sig)); #endif switch (sig) { case SIGCHLD: sig_chld = 1; break; }; #if 0 return; switch (sig) { case SIGCHLD: { int who, status; who = wait(&status); if (who == -1) { switch (errno) { case ECHILD: msg_error_print("No child processes, exiting...\n"); exit(0); break; default: break; } } switch (info->si_code) { case CLD_EXITED: /* | child has exited | */ msg_print("SIGCHLD -- child %d exited " "with status %d (%s)\n", info->si_pid, info->si_errno, strerror(info->si_errno)); break; case CLD_KILLED: /* | child was killed | */ msg_print("SIGCHLD -- child %d was killed" "by signal %d (%s)\n", info->si_pid, info->si_signo, strerror(info->si_errno)); break; case CLD_DUMPED: /* | child terminated abnormally | */ msg_print("SIGCHLD -- child %d terminated abnormaly" "by signal %d (%s)\n", info->si_pid, info->si_signo, strerror(info->si_errno)); break; case CLD_TRAPPED: /* | traced child has trapped | */ break; case CLD_STOPPED: /* | child has stopped | */ break; case CLD_CONTINUED: /* | stopped child has continued | */ break; } } break; case SIGINT: msg_print("\nSIGINT received, sending all process SIGTERM...\n"); kill(0, SIGTERM); break; default: break; } #endif } void sigserv_init(ptbl) PROCTABLE ptbl; { struct sigaction sa; memset(&sa, '\0', sizeof sa); sa.sa_sigaction = sigserv_sigaction; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(SIGQUIT, &sa, NULL); sigaction(SIGILL, &sa, NULL); sigaction(SIGABRT, &sa, NULL); sigaction(SIGFPE, &sa, NULL); sigaction(SIGKILL, &sa, NULL); sigaction(SIGSEGV, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGALRM, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGCONT, &sa, NULL); sigaction(SIGSTOP, &sa, NULL); sigaction(SIGTSTP, &sa, NULL); sigaction(SIGTTIN, &sa, NULL); sigaction(SIGTTOU, &sa, NULL); sigaction(SIGBUS, &sa, NULL); sigaction(SIGPOLL, &sa, NULL); sigaction(SIGPROF, &sa, NULL); sigaction(SIGSYS, &sa, NULL); sigaction(SIGTRAP, &sa, NULL); sigaction(SIGURG, &sa, NULL); sigaction(SIGVTALRM, &sa, NULL); sigaction(SIGXCPU, &sa, NULL); sigaction(SIGXFSZ, &sa, NULL); sigaction(SIGIOT, &sa, NULL); sigaction(SIGSTKFLT, &sa, NULL); sigaction(SIGIO, &sa, NULL); sigaction(SIGCLD, &sa, NULL); sigaction(SIGPWR, &sa, NULL); sigaction(SIGWINCH, &sa, NULL); sigaction(SIGUNUSED, &sa, NULL); #if DEBUG msg_debug_print("sigserv_init(): signal handles installed\n"); #endif sig_chld = 0; } #if 0 /* Signals. */ /* Linux 2.4.17 /usr/include/bits/signum.h */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ #define SIGUNUSED 31 #endif