ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/signal.C
Revision: 1.6
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +7 -2 lines
Log Message:
#defines to enum

File Contents

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