~ctwm/ctwm/trunk

647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
1
/*
2
 * Signal handlers
3
 */
4
5
#include "ctwm.h"
6
7
#include <signal.h>
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <unistd.h>
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
11
648.1.1 by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind
12
#include "ctwm_shutdown.h"
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
13
#include "signals.h"
14
15
16
/* Our backends */
17
static void sh_restart(int signum);
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
18
static void sh_shutdown(int signum);
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
19
20
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
21
// Internal flags for which signals have called us
22
static bool sig_restart = false;
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
23
static bool sig_shutdown = false;
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
24
647.1.12 by Matthew Fuller
Might as well move this var over here now too.
25
// External flag for whether some signal handler has set a flag that
26
// needs to trigger an action.
27
bool SignalFlag = false;
28
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
29
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
30
/**
31
 * Setup signal handlers (run during startup)
32
 */
33
void
34
setup_signal_handlers(void)
35
{
36
	// INT/QUIT/TERM: shutdown
37
	// XXX Wildly unsafe handler; to be reworked
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
38
	signal(SIGINT,  sh_shutdown);
39
	signal(SIGQUIT, sh_shutdown);
40
	signal(SIGTERM, sh_shutdown);
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
41
42
	// SIGHUP: restart
43
	signal(SIGHUP, sh_restart);
44
45
	// We don't use alarm(), but if we get the stray signal we shouldn't
46
	// die...
47
	signal(SIGALRM, SIG_IGN);
48
49
	// This should be set by default, but just in case; explicitly don't
50
	// leave zombies.
51
	signal(SIGCHLD, SIG_IGN);
52
53
	return;
54
}
55
56
647.1.8 by Matthew Fuller
Use a more general "signal recvd" flag in place of the specific
57
/**
58
 * Handle stuff set by a signal flag.  Could be a Restart, could be a
59
 * Shutdown...
60
 */
61
void
62
handle_signal_flag(Time t)
63
{
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
64
	// Restarting?
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
65
	if(sig_restart) {
66
		// In case it fails, don't loop
67
		sig_restart = false;
68
69
		// Handle
647.1.8 by Matthew Fuller
Use a more general "signal recvd" flag in place of the specific
70
		DoRestart(t);
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
71
647.1.8 by Matthew Fuller
Use a more general "signal recvd" flag in place of the specific
72
		// Shouldn't return, but exec() might fail...
73
		return;
74
	}
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
75
76
	// Shutting down?
77
	if(sig_shutdown) {
78
		// Doit
648.1.19 by Matthew Fuller
Done() -> DoShutdown(). Imperative form is more descriptive, and it's
79
		DoShutdown();
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
80
81
		// Can't return!
648.1.19 by Matthew Fuller
Done() -> DoShutdown(). Imperative form is more descriptive, and it's
82
		fprintf(stderr, "%s: DoShutdown() shouldn't return!\n", ProgramName);
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
83
		exit(1);
84
	}
85
86
	// ???
87
	fprintf(stderr, "%s: Internal error: unexpected signal flag.\n",
648.1.7 by Matthew Fuller
make indent
88
	        ProgramName);
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
89
	return;
647.1.8 by Matthew Fuller
Use a more general "signal recvd" flag in place of the specific
90
}
91
92
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
93
94
/*
95
 * Internal backend bits
96
 */
97
98
/**
99
 * Set flag to restart.  Backend for SIGHUP.
100
 */
101
static void
102
sh_restart(int signum)
103
{
104
	// Signal handler; stdio isn't async-signal-safe, write(2) is
105
	const char srf[] = ":  signal received, setting restart flag\n";
106
	write(2, ProgramName, ProgramNameLen);
107
	write(2, srf, sizeof(srf));
647.1.8 by Matthew Fuller
Use a more general "signal recvd" flag in place of the specific
108
647.1.9 by Matthew Fuller
Now we can localize the flag for "want to restart" into a static var
109
	SignalFlag = sig_restart = true;
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
110
}
647.1.10 by Matthew Fuller
Replace the direct Done() call with a flag for signal handling, so we
111
112
/**
113
 * Set flag to shutdown.  Backend for SIGTERM etc.
114
 */
115
static void
116
sh_shutdown(int signum)
117
{
118
	// Signal handler; stdio isn't async-signal-safe, write(2) is
119
	const char srf[] = ":  signal received, setting shutdown flag\n";
120
	write(2, ProgramName, ProgramNameLen);
121
	write(2, srf, sizeof(srf));
122
123
	SignalFlag = sig_shutdown = true;
124
}
125