1 /****************************************************************************
2  * Copyright (C) 1998 WIDE Project. All rights reserved.
3  * Copyright (C) 1999,2000,2001,2002 University of Tromso. All rights reserved.
4  * Copyright (C) 2002 Invenia Innovation AS. All rights reserved.
5  *
6  * Author: Feike W. Dillema, feico@pasta.cs.uit.no.
7  *         based on newbie code by Yusuke DOI, Keio Univ. Murai Lab.
8  ****************************************************************************/
9 
10 /*
11  * <$Id: ev_signal.c,v 3.21 2005/06/19 20:09:13 dillema Exp $>
12  */
13 
14 #include "totd.h"
15 
16 static void ev_signal_initiator_generic (int sig);
17 static void ev_handler_sigusr1 (void);
18 static void ev_handler_sigusr2 (void);
19 static void ev_handler_cleanup (void);
20 
21 /* event initiator (== signal handler) matrix */
22 const struct {
23 	int signal_id;		/* signal id */
24 	void (*initiator) (int);/* event initiator */
25 	void (*handler) (void);	/* event handler */
26 }   Ev_matrix[] = {
27 	{
28 		SIGINT, ev_signal_initiator_generic, ev_handler_cleanup
29 	},
30 	{
31 		SIGHUP, SIG_IGN, NULL
32 	},
33 	{
34 		SIGTERM, ev_signal_initiator_generic, ev_handler_cleanup
35 	},
36 	{
37 		SIGUSR1, ev_signal_initiator_generic, ev_handler_sigusr1
38 	},
39 	{
40 		SIGUSR2, ev_signal_initiator_generic, ev_handler_sigusr2
41 	},
42 	{
43 		-1, NULL, NULL
44 	}			/* <- terminator -- don't forget */
45 };
46 
47 /* signal event queue */
48 static Q_Set *Ev_signal_queue = NULL;
49 
50 /*
51  * (private) generic event initiator(== signal handler)
52  */
ev_signal_initiator_generic(int sig)53 static void ev_signal_initiator_generic (int sig) {
54 	int i;
55 	Ev_Sig_Data *sd_tmp;
56 
57 	if (T.debug > 2) {
58 		syslog (LOG_DEBUG, "ev_signal_initiator_generic(): start.");
59 	}
60 
61 	if (!Ev_signal_queue) {
62 		syslog (LOG_ERR, "ev_signal_initiator_generic(): no queue to process.");
63 		return;
64 	}
65 	for (i = 0; Ev_matrix[i].signal_id > 0 && Ev_matrix[i].signal_id != sig; i++);
66 
67 	sd_tmp = malloc (sizeof (Ev_Sig_Data));
68 	if (!sd_tmp) {
69 		syslog (LOG_WARNING, "ev_signal_initiator_generic(): memory exhausted");
70 		return;
71 	}
72 	sd_tmp->handler = Ev_matrix[i].handler;
73 
74 	if (enqueue (Ev_signal_queue, (void *) sd_tmp) < 0)
75 		syslog (LOG_WARNING, "ev_signal_initiator_generic(): signal queue full?");
76 
77 	return;
78 }
79 
80 /*
81  * event handlers
82  */
ev_handler_sigusr1(void)83 void ev_handler_sigusr1 (void) {
84 	syslog (LOG_INFO, "ev_handler_sigusr1(): processing SIGUSR1");
85 }
86 
ev_handler_sigusr2(void)87 void ev_handler_sigusr2 (void) {
88 	syslog (LOG_INFO, "ev_handler_sigusr2(): processing SIGUSR2");
89 }
90 
ev_handler_cleanup(void)91 void ev_handler_cleanup (void) {
92 	totd_exit (0);
93 }
94 
95 /* == end of private section == */
96 
97 /*
98  * event initializer
99  */
ev_signal_init(void)100 int ev_signal_init (void) {
101 	int i;
102 
103 	/* set event initiator */
104 	for (i = 0; Ev_matrix[i].signal_id > 0; i++)
105 		signal (Ev_matrix[i].signal_id, Ev_matrix[i].initiator);
106 
107 	/* initialize queue */
108 	Ev_signal_queue = queue_create ();
109 	if (!Ev_signal_queue)
110 		return -1;
111 
112 	return 0;
113 }
114 
115 /*
116  * event dequeue/process
117  */
ev_signal_process(void)118 void ev_signal_process (void) {
119 	Ev_Sig_Data *sd_tmp;
120 
121 	if (Ev_signal_queue)
122 		while ((sd_tmp = (Ev_Sig_Data *) dequeue (Ev_signal_queue))) {
123 			(sd_tmp->handler) ();	/* process event */
124 			free (sd_tmp);
125 		}
126 	else
127 		syslog (LOG_ERR, "ev_signal_process(): no queue to process.");
128 }
129 
130 /*
131  * finish signal routine
132  */
ev_signal_finish(void)133 void ev_signal_finish (void) {
134 	/* don't process signal. It may cause event loop */
135 	queue_destroy (Ev_signal_queue, free);
136 	Ev_signal_queue = NULL;
137 }
138