X-Git-Url: https://git.realraum.at/?a=blobdiff_plain;f=door_daemon%2Fsig_handler.c;h=7a1ad745c3e720c4f9513b162924b7136ef8a7c2;hb=bd2c78928d653160ef85e25e03e8b4e721635ac6;hp=6fd4b85820a47c502a607f961beadddbc08f64e6;hpb=e939a260125c25cca64ebb8df1ad65214ec3b2d4;p=svn42.git diff --git a/door_daemon/sig_handler.c b/door_daemon/sig_handler.c index 6fd4b85..7a1ad74 100644 --- a/door_daemon/sig_handler.c +++ b/door_daemon/sig_handler.c @@ -36,29 +36,123 @@ #include "log.h" #include +#include +#include +#include +#include + #include "sig_handler.h" -volatile sig_atomic_t signal_exit = 0; +#include + + +static int sig_pipe_fds[2]; + -void signal_init() +static void sig_handler(int sig) { - signal(SIGINT, handle_signal); - signal(SIGQUIT, handle_signal); - signal(SIGTERM, handle_signal); - signal(SIGHUP, handle_signal); - signal(SIGUSR1, handle_signal); - signal(SIGUSR2, handle_signal); + sigset_t set; + int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); + if(ret != sizeof(sigset_t)) + sigemptyset(&set); + + sigaddset(&set, sig); + ret = write(sig_pipe_fds[1], &set, sizeof(sigset_t)); +} + + +int signal_init() +{ + if(pipe(sig_pipe_fds)) { + log_printf(ERROR, "signal handling init failed (pipe error: %s)", strerror(errno)); + return -1; + } + + int i; + for(i=0; i<2; ++i) { + int fd_flags = fcntl(sig_pipe_fds[i], F_GETFL); + if(fd_flags == -1) { + log_printf(ERROR, "signal handling init failed (pipe fd[%d] read flags error: %s)", i, strerror(errno)); + return -1; + } + if(fcntl(sig_pipe_fds[i], F_SETFL, fd_flags | O_NONBLOCK) == -1){ + log_printf(ERROR, "signal handling init failed (pipe fd[%d] write flags error: %s)", i, strerror(errno)); + return -1; + } + } + + struct sigaction act; + act.sa_handler = sig_handler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + + if((sigaction(SIGINT, &act, NULL) < 0) || + (sigaction(SIGQUIT, &act, NULL) < 0) || + (sigaction(SIGTERM, &act, NULL) < 0) || + (sigaction(SIGHUP, &act, NULL) < 0) || + (sigaction(SIGUSR1, &act, NULL) < 0) || + (sigaction(SIGUSR2, &act, NULL) < 0)) { + + log_printf(ERROR, "signal handling init failed (sigaction error: %s)", strerror(errno)); + close(sig_pipe_fds[0]); + close(sig_pipe_fds[1]); + } + + return sig_pipe_fds[0]; } -void handle_signal(int sig) +int signal_handle() { - switch(sig) { - case SIGINT: log_printf(NOTICE, "SIG-Int caught, exitting"); signal_exit = 1; break; - case SIGQUIT: log_printf(NOTICE, "SIG-Quit caught, exitting"); signal_exit = 1; break; - case SIGTERM: log_printf(NOTICE, "SIG-Term caught, exitting"); signal_exit = 1; break; - case SIGHUP: log_printf(NOTICE, "SIG-Hup caught"); break; - case SIGUSR1: log_printf(NOTICE, "SIG-Usr1 caught"); break; - case SIGUSR2: log_printf(NOTICE, "SIG-Usr2 caught"); break; - default: log_printf(NOTICE, "Signal %d caught, ignoring", sig); break; + sigset_t set, oldset, tmpset; + + sigemptyset(&tmpset); + sigaddset(&tmpset, SIGINT); + sigaddset(&tmpset, SIGQUIT); + sigaddset(&tmpset, SIGTERM); + sigaddset(&tmpset, SIGHUP); + sigaddset(&tmpset, SIGUSR1); + sigaddset(&tmpset, SIGUSR2); + sigprocmask(SIG_BLOCK, &tmpset, &oldset); + + int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); + if(ret != sizeof(sigset_t)) + sigemptyset(&set); + + int return_value = 0; + int sig; + for(sig=1; sig < _NSIG; ++sig) { + if(sigismember(&set, sig)) { + switch(sig) { + case SIGINT: log_printf(NOTICE, "SIG-Int caught, exitting"); return_value = 1; break; + case SIGQUIT: log_printf(NOTICE, "SIG-Quit caught, exitting"); return_value = 1; break; + case SIGTERM: log_printf(NOTICE, "SIG-Term caught, exitting"); return_value = 1; break; + case SIGHUP: log_printf(NOTICE, "SIG-Hup caught"); break; + case SIGUSR1: log_printf(NOTICE, "SIG-Usr1 caught"); break; + case SIGUSR2: log_printf(NOTICE, "SIG-Usr2 caught"); break; + default: log_printf(WARNING, "unknown signal %d caught, ignoring", sig); break; + } + sigdelset(&set, sig); + } } + + sigprocmask(SIG_SETMASK, &oldset, NULL); + return return_value; +} + +void signal_stop() +{ + struct sigaction act; + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + sigaction(SIGINT, &act, NULL); + sigaction(SIGQUIT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGUSR1, &act, NULL); + sigaction(SIGUSR2, &act, NULL); + + close(sig_pipe_fds[0]); + close(sig_pipe_fds[1]); }