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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
/*
* This file contains the signal handler which cleanly exists
* when an appropriate signal is received.
*/
#include "ledd.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
static void signal_sig(int sig);
static void signal_abort(int sig);
static void signal_exit(void);
static options *sigopts;
/*
* Sets the exit signal handler for a few common signals.
*/
void signal_set_handler(options *opts) {
/* Save a local copy of options for handler. */
sigopts=opts;
atexit(signal_exit);
#ifdef SIGINT
signal(SIGINT,signal_sig);
#endif
#ifdef SIGTERM
signal(SIGTERM,signal_sig);
#endif
#ifdef SIGABRT
signal(SIGABRT,signal_sig);
#endif
return;
}
/*
* Sets abort signal to exit silently with error code 1.
*/
void signal_ignore_abort(void) {
#ifdef SIGABRT
signal(SIGABRT,signal_abort);
#endif
}
/*
* Simply exits quietly with error code 1. Used before the real signal
* handler is placed.
*/
static void signal_abort(int sig) {
exit(1);
}
/*
* The actual signal handler. This handles the exit of the program nicely
* closing all descriptors and killing all children.
*/
static void signal_sig(int sig) {
static gint doneit=0;
GSList *list;
File *p;
/* Don't do recursion */
if (doneit)
return;
doneit=1;
/* Report exit. */
if (sig==-1)
g_message("exiting cleanly on exit()");
else
g_message("exiting cleanly on signal %d (%s)",
sig,g_strsignal(sig));
/* Startup script */
for (list=sigopts->startup; list; list=g_slist_next(list)) {
if (list->data==NULL)
continue;
p=list->data;
if (p->pid > 0)
kill(p->pid,SIGTERM);
/* wait() not neccessary, as ledd is exiting anyway. */
}
/* File handles */
pipe_close_all(sigopts);
/* LEDs */
led_set_all_normal(sigopts);
/* pidfile */
startup_pidfile_remove(sigopts);
/* Memory - how cares? It's freed anyway. */
/* Logging off... */
log_close(sigopts->logging);
exit(0);
}
/*
* atexit() handler. Only calls sig_handler(-1).
*/
static void signal_exit(void) {
signal_sig(-1);
return;
}
|