ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/signal.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +8 -6 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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