]>
Commit | Line | Data |
---|---|---|
189935b1 | 1 | /* |
2 | * IRC - Internet Relay Chat, ircd/ircd_signal.c | |
3 | * Copyright (C) 1990 Jarkko Oikarinen and | |
4 | * University of Oulu, Computing Center | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 1, or (at your option) | |
9 | * any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | */ | |
20 | /** @file | |
21 | * @brief Signal handlers for ircu. | |
22 | * @version $Id: ircd_signal.c,v 1.6 2004/12/11 05:13:45 klmitch Exp $ | |
23 | */ | |
24 | #include "config.h" | |
25 | ||
26 | #include "ircd.h" | |
27 | #include "ircd_events.h" | |
28 | #include "ircd_log.h" | |
29 | #include "ircd_signal.h" | |
30 | #include "s_conf.h" | |
31 | ||
32 | /* #include <assert.h> -- Now using assert in ircd_log.h */ | |
33 | #include <signal.h> | |
34 | ||
35 | /** Counts various types of signals that we receive. */ | |
36 | static struct tag_SignalCounter { | |
37 | unsigned int alrm; /**< Received SIGALRM count. */ | |
38 | unsigned int hup; /**< Received SIGHUP count. */ | |
39 | } SignalCounter; | |
40 | ||
41 | /** Event generator for SIGHUP. */ | |
42 | static struct Signal sig_hup; | |
43 | /** Event generator for SIGINT. */ | |
44 | static struct Signal sig_int; | |
45 | /** Event generator for SIGTERM. */ | |
46 | static struct Signal sig_term; | |
47 | ||
48 | /** Signal handler for SIGALRM. | |
49 | * @param[in] sig Signal number (ignored). | |
50 | */ | |
51 | static void sigalrm_handler(int sig) | |
52 | { | |
53 | ++SignalCounter.alrm; | |
54 | } | |
55 | ||
56 | /** Signal callback for SIGTERM. | |
57 | * @param[in] ev Signal event descriptor. | |
58 | */ | |
59 | static void sigterm_callback(struct Event* ev) | |
60 | { | |
61 | assert(0 != ev_signal(ev)); | |
62 | assert(ET_SIGNAL == ev_type(ev)); | |
63 | assert(SIGTERM == sig_signal(ev_signal(ev))); | |
64 | assert(SIGTERM == ev_data(ev)); | |
65 | ||
66 | server_die("received signal SIGTERM"); | |
67 | } | |
68 | ||
69 | /** Signal callback for SIGHUP. | |
70 | * @param[in] ev Signal event descriptor. | |
71 | */ | |
72 | static void sighup_callback(struct Event* ev) | |
73 | { | |
74 | assert(0 != ev_signal(ev)); | |
75 | assert(ET_SIGNAL == ev_type(ev)); | |
76 | assert(SIGHUP == sig_signal(ev_signal(ev))); | |
77 | assert(SIGHUP == ev_data(ev)); | |
78 | ||
79 | ++SignalCounter.hup; | |
80 | rehash(&me, 1); | |
81 | } | |
82 | ||
83 | /** Signal callback for SIGINT. | |
84 | * @param[in] ev Signal event descriptor. | |
85 | */ | |
86 | static void sigint_callback(struct Event* ev) | |
87 | { | |
88 | assert(0 != ev_signal(ev)); | |
89 | assert(ET_SIGNAL == ev_type(ev)); | |
90 | assert(SIGINT == sig_signal(ev_signal(ev))); | |
91 | assert(SIGINT == ev_data(ev)); | |
92 | ||
93 | server_restart("caught signal: SIGINT"); | |
94 | } | |
95 | ||
96 | /** Register all necessary signal handlers. */ | |
97 | void setup_signals(void) | |
98 | { | |
99 | struct sigaction act; | |
100 | ||
101 | act.sa_handler = SIG_IGN; | |
102 | act.sa_flags = 0; | |
103 | sigemptyset(&act.sa_mask); | |
104 | sigaddset(&act.sa_mask, SIGPIPE); | |
105 | sigaddset(&act.sa_mask, SIGALRM); | |
106 | #ifdef SIGWINCH | |
107 | sigaddset(&act.sa_mask, SIGWINCH); | |
108 | sigaction(SIGWINCH, &act, 0); | |
109 | #endif | |
110 | sigaction(SIGPIPE, &act, 0); | |
111 | ||
112 | act.sa_handler = sigalrm_handler; | |
113 | sigaction(SIGALRM, &act, 0); | |
114 | ||
115 | signal_add(&sig_hup, sighup_callback, 0, SIGHUP); | |
116 | signal_add(&sig_int, sigint_callback, 0, SIGINT); | |
117 | signal_add(&sig_term, sigterm_callback, 0, SIGTERM); | |
118 | ||
119 | #ifdef HAVE_RESTARTABLE_SYSCALLS | |
120 | /* | |
121 | * At least on Apollo sr10.1 it seems continuing system calls | |
122 | * after signal is the default. The following 'siginterrupt' | |
123 | * should change that default to interrupting calls. | |
124 | */ | |
125 | siginterrupt(SIGALRM, 1); | |
126 | #endif | |
127 | } | |
128 |