ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/signal.C
Revision: 1.5
Committed: Thu Aug 30 19:56:26 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -1 lines
Log Message:
- put faultcodes into their own namespace
- removed old files
- limited header garbage in atheme.h
- macros to inline bools for connection_t::is_*
- put some connection_t functions into the connection_t class

File Contents

# Content
1 /*
2 * signal.C: Signal-handling routines.
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id: signal.C,v 1.4 2007-08-28 17:08:12 pippijn Exp $";
9
10 #include "atheme.h"
11 #include <ermyth/database.h>
12 #include "uplink.h"
13 #include "internal.h"
14 #include "connection.h"
15
16 typedef void (*signal_handler_t) (int);
17
18 static signal_handler_t
19 signal_install_handler_full (int signum, signal_handler_t handler, int *sigtoblock, size_t sigtoblocksize)
20 {
21 struct sigaction action, old_action;
22 size_t i;
23
24 action.sa_handler = handler;
25 action.sa_flags = SA_RESTART;
26
27 sigemptyset (&action.sa_mask);
28
29 for (i = 0; i < sigtoblocksize; i++)
30 sigaddset (&action.sa_mask, sigtoblock[i]);
31
32 if (sigaction (signum, &action, &old_action) == -1)
33 {
34 slog (LG_DEBUG, "Failed to install signal handler for signal %d", signum);
35 return NULL;
36 }
37
38 return old_action.sa_handler;
39 }
40
41 /*
42 * A version of signal(2) that works more reliably across different
43 * platforms.
44 *
45 * It restarts interrupted system calls, does not reset the handler,
46 * and blocks the same signal from within the handler.
47 */
48 static signal_handler_t
49 signal_install_handler (int signum, signal_handler_t handler)
50 {
51 return signal_install_handler_full (signum, handler, NULL, 0);
52 }
53
54 static void
55 signal_empty_handler (int signum)
56 {
57 /* do nothing */
58 }
59
60 static void
61 signal_hup_handler (int signum)
62 {
63 /* rehash */
64 slog (LG_INFO, "sighandler(): got SIGHUP, rehashing %s", config_file);
65
66 wallops (_("Got SIGHUP; reloading \2%s\2."), config_file);
67
68 snoop ("UPDATE: \2%s\2", "system console");
69 wallops (_("Updating database by request of \2%s\2."), "system console");
70 expire_check (NULL);
71 backend->save ();
72
73 snoop ("REHASH: \2%s\2", "system console");
74 wallops (_("Rehashing \2%s\2 by request of \2%s\2."), config_file, "system console");
75
76 /* reload the config, opening other logs besides the core log if needed. */
77 if (!conf_rehash ())
78 wallops (_("REHASH of \2%s\2 failed. Please correct any errors in the file and try again."), config_file);
79
80 return;
81 }
82
83 static void
84 signal_int_handler (int signum)
85 {
86 /* usually caused by ^C */
87 if (runflags & RF_LIVE)
88 {
89 wallops (_("Exiting on signal %d."), SIGINT);
90 if (chansvs.me != NULL && chansvs.me->me != NULL)
91 phandler->quit_sts (chansvs.me->me, "caught interrupt");
92 me.connected = false;
93 slog (LG_INFO, "sighandler(): caught interrupt; exiting...");
94 runflags |= RF_SHUTDOWN;
95 }
96 else if (!(runflags & RF_LIVE))
97 {
98 wallops (_("Got SIGINT; restarting."));
99
100 snoop ("UPDATE: \2%s\2", "system console");
101 wallops (_("Updating database by request of \2%s\2."), "system console");
102 expire_check (NULL);
103 backend->save ();
104
105 snoop ("RESTART: \2%s\2", "system console");
106 wallops (_("Restarting by request of \2%s\2."), "system console");
107
108 slog (LG_INFO, "sighandler(): restarting...");
109 runflags |= RF_RESTART;
110 }
111 }
112
113 static void
114 signal_term_handler (int signum)
115 {
116 wallops (_("Exiting on signal %d."), SIGTERM);
117 slog (LG_INFO, "sighandler(): got SIGTERM; exiting...");
118 runflags |= RF_SHUTDOWN;
119 }
120
121 static void
122 signal_usr2_handler (int signum)
123 {
124 wallops (_("Got SIGUSR2; restarting."));
125
126 snoop ("UPDATE: \2%s\2", "system console");
127 wallops (_("Updating database by request of \2%s\2."), "system console");
128 expire_check (NULL);
129 backend->save ();
130
131 snoop ("RESTART: \2%s\2", "system console");
132 wallops (_("Restarting by request of \2%s\2."), "system console");
133
134 slog (LG_INFO, "sighandler(): restarting...");
135 runflags |= RF_RESTART;
136 }
137
138 /* XXX */
139 static void signal_usr1_handler (int signum) __attribute__ ((__noreturn__));
140 static void
141 signal_usr1_handler (int signum)
142 {
143 if (me.connected && curr_uplink != NULL && curr_uplink->conn != NULL)
144 {
145 if (chansvs.nick != NULL)
146 {
147 write (curr_uplink->conn->fd, ":", 1);
148 write (curr_uplink->conn->fd, chansvs.nick, strlen (chansvs.nick));
149 write (curr_uplink->conn->fd, " QUIT :Out of memory!\r\n", 23);
150 }
151 write (curr_uplink->conn->fd, "ERROR :Panic! Out of memory.\r\n", 30);
152 }
153 if (runflags & (RF_LIVE | RF_STARTING))
154 write (2, "Out of memory!\n", 15);
155 abort ();
156 }
157
158 void
159 init_signal_handlers (void)
160 {
161 signal_install_handler (SIGHUP, signal_hup_handler);
162 signal_install_handler (SIGINT, signal_int_handler);
163 signal_install_handler (SIGTERM, signal_term_handler);
164 signal_install_handler (SIGPIPE, signal_empty_handler);
165
166 signal_install_handler (SIGUSR1, signal_usr1_handler);
167 signal_install_handler (SIGUSR2, signal_usr2_handler);
168 }