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