src/lib/signals.c
changeset 61 9f7ecf7bf699
equal deleted inserted replaced
60:b17d2cf35504 61:9f7ecf7bf699
       
     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