From 91511db7500439088b8b3bb08ce6ee6f8f8e6499 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 18 Dec 2004 23:29:50 +0000 Subject: rename src/ to libdaemon/ git-svn-id: file:///home/lennart/svn/public/libdaemon/trunk@71 153bfa13-eec0-0310-be40-b0cb6a0e1b4b --- libdaemon/dsignal.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 libdaemon/dsignal.c (limited to 'libdaemon/dsignal.c') diff --git a/libdaemon/dsignal.c b/libdaemon/dsignal.c new file mode 100644 index 0000000..2eafc0c --- /dev/null +++ b/libdaemon/dsignal.c @@ -0,0 +1,152 @@ +/* $Id$ */ + +/* + * This file is part of libdaemon. + * + * libdaemon is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libdaemon is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libdaemon; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "dsignal.h" +#include "dlog.h" +#include "dnonblock.h" + +static int _signal_pipe[2] = { -1, -1 }; + +static void _sigfunc(int s) { + write(_signal_pipe[1], &s, sizeof(s)); +} + +static int _init(void) { + + if (_signal_pipe[0] < 0 || _signal_pipe[1] < 0) { + if (pipe(_signal_pipe) < 0) { + daemon_log(LOG_ERR, "pipe(): %s", strerror(errno)); + return -1; + } + + if (daemon_nonblock(_signal_pipe[0], 1) < 0 || daemon_nonblock(_signal_pipe[1], 1) < 0) + return -1; + + } + + return 0; +} + +int daemon_signal_install(int s){ + sigset_t sigset; + struct sigaction sa; + + if (_init() < 0) + return -1; + + if (sigemptyset(&sigset) < 0) { + daemon_log(LOG_ERR, "sigemptyset(): %s", strerror(errno)); + return -1; + } + + if (sigaddset(&sigset, s) < 0) { + daemon_log(LOG_ERR, "sigaddyset(): %s", strerror(errno)); + return -1; + } + + if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) { + daemon_log(LOG_ERR, "sigprocmask(): %s", strerror(errno)); + return -1; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = _sigfunc; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction(s, &sa, NULL) < 0) { + daemon_log(LOG_ERR, "sigaction(%s, ...) failed: %s", strsignal(s), strerror(errno)); + return -1; + } + + return 0; +} + +int daemon_signal_init(int s, ...) { + int sig, r = 0; + + va_list ap; + va_start(ap, s); + + if (_init() < 0) + return -1; + + sig = s; + while (sig > 0) { + if (daemon_signal_install(sig) < 0) { + r = -1; + break; + } + + sig = va_arg(ap, int); + } + + va_end(ap); + + + return r; +} + +void daemon_signal_done(void) { + if (_signal_pipe[0] != -1) + close(_signal_pipe[0]); + + if (_signal_pipe[1] != -1) + close(_signal_pipe[1]); + + _signal_pipe[0] = _signal_pipe[1] = -1; +} + +int daemon_signal_next(void) { + int s; + ssize_t r; + + if ((r = read(_signal_pipe[0], &s, sizeof(s))) == sizeof(s)) + return s; + + + if (r < 0) { + + if (errno == EAGAIN) + return 0; + else { + daemon_log(LOG_ERR, "read(signal_pipe[0], ...): %s", strerror(errno)); + return -1; + } + } + + daemon_log(LOG_ERR, "Short read() on signal pipe."); + return -1; +} + +int daemon_signal_fd(void) { + return _signal_pipe[0]; +} -- cgit