ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/signal.C
Revision: 1.1
Committed: Thu Jul 19 08:24:59 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Log Message:
initial import. the most important changes since Atheme are:
- fixed many memory leaks
- fixed many bugs
- converted to C++ and use more STL containers
- added a (not very enhanced yet) perl module
- greatly improved XML-RPC speed
- added a JSON-RPC module with code from json-cpp
- added a valgrind memcheck module to operserv
- added a more object oriented base64 implementation
- added a specialised unit test framework
- improved stability
- use gettimeofday() if available
- reworked adding/removing commands
- MemoServ IGNORE DEL can now remove indices

File Contents

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