diff options
| author | Roy Marples <roy@marples.name> | 2006-11-27 20:23:22 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2006-11-27 20:23:22 +0000 |
| commit | cced195e703c548e7375727ea91bbdcd76aae517 (patch) | |
| tree | 6c97679eedd1d687263f7d65742b02bedd93895f /signals.c | |
| download | dhcpcd-cced195e703c548e7375727ea91bbdcd76aae517.tar.xz | |
Add dhcpcd-3 re-write
Diffstat (limited to 'signals.c')
| -rw-r--r-- | signals.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/signals.c b/signals.c new file mode 100644 index 00000000..b565b8d2 --- /dev/null +++ b/signals.c @@ -0,0 +1,91 @@ +/* + * Shameless taken from udhcp as I think it's a good idea. + * Signal pipe infrastructure. A reliable way of delivering signals. + * + * Russ Dill <Russ.Dill@asu.edu> December 2003 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <sys/socket.h> +#include <sys/select.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +#include "logger.h" + +static int signal_pipe[2]; + +static void signal_handler (int sig) +{ + if (send (signal_pipe[1], &sig, sizeof (sig), MSG_DONTWAIT) < 0) + logger (LOG_ERR, "Could not send signal: %s", strerror (errno)); +} + + +/* Call this before doing anything else. Sets up the socket pair + * and installs the signal handler */ +void signal_setup(void) +{ + int i; + int flags; + + socketpair (AF_UNIX, SOCK_STREAM, 0, signal_pipe); + + /* Stop any scripts from inheriting us */ + for (i = 0; i < 2; i++) + if ((flags = fcntl (signal_pipe[i], F_GETFD, 0)) < 0 || + fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) < 0) + logger (LOG_ERR ,"fcntl: %s", strerror (errno)); + + signal (SIGHUP, signal_handler); + signal (SIGALRM, signal_handler); + signal (SIGTERM, signal_handler); + signal (SIGINT, signal_handler); +} + + +/* Quick little function to setup the rfds. Will return the + * max_fd for use with select. Limited in that you can only pass + * one extra fd */ +int signal_fd_set (fd_set *rfds, int extra_fd) +{ + FD_ZERO (rfds); + FD_SET (signal_pipe[0], rfds); + if (extra_fd >= 0) + FD_SET (extra_fd, rfds); + return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd; +} + + +/* Read a signal from the signal pipe. Returns 0 if there is + * no signal, -1 on error (and sets errno appropriately), and + * your signal on success */ +int signal_read (fd_set *rfds) +{ + int sig; + + if (!FD_ISSET (signal_pipe[0], rfds)) + return 0; + + if (read (signal_pipe[0], &sig, sizeof (sig)) < 0) + return -1; + + return sig; +} + |
