]> mj.ucw.cz Git - libucw.git/blob - ucw/sighandler.c
Released as 6.5.13.
[libucw.git] / ucw / sighandler.c
1 /*
2  *      UCW Library -- Catching of signals and calling callback functions
3  *
4  *      (c) 2004, Robert Spalek <robert@ucw.cz>
5  *      (c) 2006 Martin Mares <mj@ucw.cz>
6  */
7
8 #include <ucw/lib.h>
9 #include <ucw/threads.h>
10 #include <ucw/sighandler.h>
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <signal.h>
15
16 static int sig_handler_nest[NSIG];
17 static struct sigaction sig_handler_old[NSIG];
18
19 static void
20 signal_handler_internal(int sig)
21 {
22   struct ucwlib_context *ctx = ucwlib_thread_context();
23   if (!ctx->signal_handlers || !ctx->signal_handlers[sig] || ctx->signal_handlers[sig](sig))
24     abort();
25 }
26
27 void
28 handle_signal(int signum)
29 {
30   ucwlib_lock();
31   if (!sig_handler_nest[signum]++)
32     {
33       struct sigaction act;
34       bzero(&act, sizeof(act));
35       act.sa_handler = signal_handler_internal;
36       act.sa_flags = SA_NODEFER;
37       if (sigaction(signum, &act, &sig_handler_old[signum]) < 0)
38         die("sigaction: %m");
39     }
40   ucwlib_unlock();
41 }
42
43 void
44 unhandle_signal(int signum)
45 {
46   ucwlib_lock();
47   ASSERT(sig_handler_nest[signum]);
48   if (!--sig_handler_nest[signum])
49     {
50       if (sigaction(signum, &sig_handler_old[signum], NULL) < 0)
51         die("sigaction: %m");
52     }
53   ucwlib_unlock();
54 }
55
56 ucw_sighandler_t
57 set_signal_handler(int signum, ucw_sighandler_t newh)
58 {
59   struct ucwlib_context *ctx = ucwlib_thread_context();
60   if (!ctx->signal_handlers)
61     ctx->signal_handlers = xmalloc_zero(NSIG * sizeof(ucw_sighandler_t));
62   ucw_sighandler_t old = ctx->signal_handlers[signum];
63   ctx->signal_handlers[signum] = newh;
64   return old;
65 }