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