terom@3: #define _GNU_SOURCE terom@3: #include terom@3: #include terom@3: #include terom@3: #include terom@3: terom@3: #include "signals.h" terom@3: #include "common.h" terom@3: terom@3: struct signals { terom@3: struct event_base *ev_base; terom@3: terom@3: struct signal { terom@3: struct event *ev; terom@3: } sig_list[MAX_SIGNALS]; terom@3: terom@3: int sig_count; terom@3: }; terom@3: terom@3: void signals_loopexit (int signal, short event, void *arg) { terom@3: struct signals *signals = arg; terom@3: terom@3: INFO("[signal] caught %s: exiting the event loop", strsignal(signal)); terom@3: terom@3: if (event_base_loopexit(signals->ev_base, NULL)) terom@3: FATAL("event_base_loopexit"); terom@3: } terom@3: terom@3: void signals_ignore (int signal, short event, void *arg) { terom@3: struct signals *signals = arg; terom@3: terom@3: (void) signals; terom@3: terom@3: /* ignore */ terom@3: } terom@3: terom@3: struct signals *signals_alloc (struct event_base *ev_base) { terom@3: struct signals *signals = NULL; terom@3: terom@3: if ((signals = calloc(1, sizeof(*signals))) == NULL) terom@3: ERROR("calloc"); terom@3: terom@3: // simple attributes terom@3: signals->ev_base = ev_base; terom@3: terom@3: // done terom@3: return signals; terom@3: terom@3: error: terom@3: return NULL; terom@3: } terom@3: terom@3: int signals_add (struct signals *signals, int sigval, void (*sig_handler)(evutil_socket_t, short, void *)) { terom@3: struct signal *sig_info; terom@3: terom@3: // find our sig_info terom@3: assert(signals->sig_count < MAX_SIGNALS); terom@3: sig_info = &signals->sig_list[signals->sig_count++]; terom@3: terom@3: // set up the libevent signal events terom@3: if ((sig_info->ev = signal_new(signals->ev_base, sigval, sig_handler, signals)) == NULL) terom@3: PERROR("signal_new"); terom@3: terom@3: if (signal_add(sig_info->ev, NULL)) terom@3: PERROR("signal_add"); terom@3: terom@3: // success terom@3: return 0; terom@3: terom@3: error: terom@3: return -1; terom@3: } terom@3: terom@3: struct signals *signals_default (struct event_base *ev_base) { terom@3: struct signals *signals = NULL; terom@3: terom@3: // alloc signals terom@3: if ((signals = signals_alloc(ev_base)) == NULL) terom@3: return NULL; terom@3: terom@3: // add the set of default signals terom@3: if ( signals_add(signals, SIGPIPE, &signals_ignore) terom@3: || signals_add(signals, SIGINT, &signals_loopexit) terom@3: ) ERROR("signals_add"); terom@3: terom@3: // success terom@3: return signals; terom@3: terom@3: error: terom@3: if (signals) terom@3: signals_free(signals); terom@3: terom@3: return NULL; terom@3: } terom@3: terom@3: void signals_free (struct signals *signals) { terom@3: int i; terom@3: terom@3: // free all events terom@3: for (i = 0; i < signals->sig_count; i++) { terom@3: if (signal_del(signals->sig_list[i].ev)) terom@3: PWARNING("signal_del"); terom@3: terom@3: } terom@3: terom@3: // free the info itself terom@3: free(signals); terom@3: } terom@3: