X-Git-Url: https://git.grml.org/?a=blobdiff_plain;f=udhcp%2Fsignalpipe.c;fp=udhcp%2Fsignalpipe.c;h=074c8a6037ea2d752cd3df70bfbd2882ac6fcb70;hb=d0c93c365e33f6970a0417dff7009a4a4fe2a3b1;hp=0000000000000000000000000000000000000000;hpb=184a9d3153e3fae4fa1ea20a186c12e9c0a83db2;p=grml-terminalserver.git diff --git a/udhcp/signalpipe.c b/udhcp/signalpipe.c new file mode 100644 index 0000000..074c8a6 --- /dev/null +++ b/udhcp/signalpipe.c @@ -0,0 +1,78 @@ +/* signalpipe.c + * + * Signal pipe infrastructure. A reliable way of delivering signals. + * + * Russ Dill 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 +#include +#include +#include +#include + + +#include "signalpipe.h" +#include "common.h" + +static int signal_pipe[2]; + +static void signal_handler(int sig) +{ + if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) + DEBUG(LOG_ERR, "Could not send signal: %m"); +} + + +/* Call this before doing anything else. Sets up the socket pair + * and installs the signal handler */ +void udhcp_sp_setup(void) +{ + socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe); + signal(SIGUSR1, signal_handler); + signal(SIGUSR2, signal_handler); + signal(SIGTERM, 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 udhcp_sp_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 udhcp_sp_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; +}