|
1 #define _GNU_SOURCE |
|
2 #include <signal.h> |
|
3 #include <string.h> |
|
4 #include <stdlib.h> |
|
5 #include <assert.h> |
|
6 |
|
7 #include "signals.h" |
|
8 #include "log.h" |
|
9 |
|
10 struct signals { |
|
11 struct event_base *ev_base; |
|
12 |
|
13 struct signal { |
|
14 struct event *ev; |
|
15 } sig_list[MAX_SIGNALS]; |
|
16 |
|
17 int sig_count; |
|
18 }; |
|
19 |
|
20 void signals_loopexit (int signal, short event, void *arg) { |
|
21 struct signals *signals = arg; |
|
22 |
|
23 (void) event; |
|
24 |
|
25 INFO("[signal] caught %s: exiting the event loop", strsignal(signal)); |
|
26 |
|
27 if (event_base_loopexit(signals->ev_base, NULL)) |
|
28 FATAL("event_base_loopexit"); |
|
29 } |
|
30 |
|
31 void signals_ignore (int signal, short event, void *arg) { |
|
32 struct signals *signals = arg; |
|
33 |
|
34 (void) signal; |
|
35 (void) event; |
|
36 (void) arg; |
|
37 (void) signals; |
|
38 |
|
39 /* ignore */ |
|
40 } |
|
41 |
|
42 struct signals *signals_alloc (struct event_base *ev_base) { |
|
43 struct signals *signals = NULL; |
|
44 |
|
45 if ((signals = calloc(1, sizeof(*signals))) == NULL) |
|
46 ERROR("calloc"); |
|
47 |
|
48 // simple attributes |
|
49 signals->ev_base = ev_base; |
|
50 |
|
51 // done |
|
52 return signals; |
|
53 |
|
54 error: |
|
55 return NULL; |
|
56 } |
|
57 |
|
58 int signals_add (struct signals *signals, int sigval, void (*sig_handler)(evutil_socket_t, short, void *)) { |
|
59 struct signal *sig_info; |
|
60 |
|
61 // find our sig_info |
|
62 assert(signals->sig_count < MAX_SIGNALS); |
|
63 sig_info = &signals->sig_list[signals->sig_count++]; |
|
64 |
|
65 // set up the libevent signal events |
|
66 if ((sig_info->ev = evsignal_new(signals->ev_base, sigval, sig_handler, signals)) == NULL) |
|
67 PERROR("signal_new"); |
|
68 |
|
69 if (evsignal_add(sig_info->ev, NULL)) |
|
70 PERROR("signal_add"); |
|
71 |
|
72 // success |
|
73 return 0; |
|
74 |
|
75 error: |
|
76 return -1; |
|
77 } |
|
78 |
|
79 struct signals *signals_default (struct event_base *ev_base) { |
|
80 struct signals *signals = NULL; |
|
81 |
|
82 // alloc signals |
|
83 if ((signals = signals_alloc(ev_base)) == NULL) |
|
84 return NULL; |
|
85 |
|
86 // add the set of default signals |
|
87 if ( signals_add(signals, SIGPIPE, &signals_ignore) |
|
88 || signals_add(signals, SIGINT, &signals_loopexit) |
|
89 ) ERROR("signals_add"); |
|
90 |
|
91 // success |
|
92 return signals; |
|
93 |
|
94 error: |
|
95 if (signals) |
|
96 signals_free(signals); |
|
97 |
|
98 return NULL; |
|
99 } |
|
100 |
|
101 void signals_free (struct signals *signals) { |
|
102 int i; |
|
103 |
|
104 // free all events |
|
105 for (i = 0; i < signals->sig_count; i++) { |
|
106 if (evsignal_del(signals->sig_list[i].ev)) |
|
107 PWARNING("signal_del"); |
|
108 |
|
109 } |
|
110 |
|
111 // free the info itself |
|
112 free(signals); |
|
113 } |
|
114 |