1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
/*
* Copyright (C) 2003-2016 Renzo Davoli, Ludovico Gardenghi. University of Bologna
*
* signal handler
*
* VDE 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, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <selfsighandler.h>
static void (*cleanupcopy)(void);
static void sig_handler(int sig)
{
cleanupcopy();
signal(sig, SIG_DFL);
if (sig == SIGTERM)
_exit(0);
else
kill(-getpgrp(), sig);
}
void setsighandlers(void (*cleanup)(void))
{
/* setting signal handlers.
* sets clean termination for SIGHUP, SIGINT and SIGTERM, and simply
* ignores all the others signals which could cause termination. */
struct { int sig; const char *name; int ignore; } signals[] = {
{ SIGHUP, "SIGHUP", 0 },
{ SIGINT, "SIGINT", 0 },
{ SIGPIPE, "SIGPIPE", 1 },
{ SIGALRM, "SIGALRM", 1 },
{ SIGTERM, "SIGTERM", 0 },
{ SIGUSR1, "SIGUSR1", 1 },
{ SIGUSR2, "SIGUSR2", 1 },
{ SIGPROF, "SIGPROF", 1 },
{ SIGVTALRM, "SIGVTALRM", 1 },
#ifdef SIGPOLL
{ SIGPOLL, "SIGPOLL", 1 },
#ifdef SIGSTKFLT
{ SIGSTKFLT, "SIGSTKFLT", 1 },
#endif
{ SIGIO, "SIGIO", 1 },
{ SIGPWR, "SIGPWR", 1 },
#ifdef SIGUNUSED
{ SIGUNUSED, "SIGUNUSED", 1 },
#endif
#endif
#ifdef VDE_DARWIN
{ SIGXCPU, "SIGXCPU", 1 },
{ SIGXFSZ, "SIGXFSZ", 1 },
#endif
{ 0, NULL, 0 }
};
int i;
struct sigaction sa = {
.sa_handler = sig_handler,
.sa_flags = 0};
sigfillset(&sa.sa_mask);
for(i = 0; signals[i].sig != 0; i++)
if (!signals[i].ignore)
if (sigaction(signals[i].sig, &sa, NULL) < 0)
perror("Setting handler");
for(i = 0; signals[i].sig != 0; i++)
if (signals[i].ignore)
if (signal(signals[i].sig, SIG_IGN) == SIG_ERR)
perror("Setting handler");
cleanupcopy = cleanup;
}
|