annotate src/lib/lib-signals.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents cc3d5de90348
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21389
diff changeset
1 /* Copyright (c) 2001-2017 Dovecot authors, see the included COPYING file */
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
4 #include "ioloop.h"
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
5 #include "fd-close-on-exec.h"
10493
2d7e2e76a100 lib-signals: Set signal pipe fds non-blocking to make sure read/write doesn't hang.
Timo Sirainen <tss@iki.fi>
parents: 9905
diff changeset
6 #include "fd-set-nonblock.h"
22023
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
7 #include "write-full.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "lib-signals.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
22023
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
10 #include <stdio.h>
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include <signal.h>
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
12 #include <unistd.h>
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
13
13022
a32debbe3496 Increased highest signal number limit. HP-UX can use at least 44.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
14 #define MAX_SIGNAL_VALUE 63
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
15
12117
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
16 #define SIGNAL_IS_TERMINAL(signo) \
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
17 ((signo) == SIGINT || (signo) == SIGQUIT || (signo) == SIGTERM)
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
18
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
19 #if !defined(SA_SIGINFO) && !defined(SI_NOINFO)
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
20 /* without SA_SIGINFO we don't know what the real code is. we need SI_NOINFO
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
21 to make sure lib_signal_code_to_str() returns "". */
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
22 # define SI_NOINFO -1
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
23 #endif
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
24
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
25 struct signal_handler {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
26 signal_handler_t *handler;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
27 void *context;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
29 enum libsig_flags flags;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
30 struct signal_handler *next;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
31 };
2854
e0db9324e799 Changed lib_signal_hup to lib_signal_hup_count.
Timo Sirainen <tss@iki.fi>
parents: 2490
diff changeset
32
12117
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
33 volatile unsigned int signal_term_counter = 0;
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
34
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
35 /* Remember that these are accessed inside signal handler which may be called
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
36 even while we're initializing/deinitializing. Try hard to keep everything
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
37 in consistent state. */
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
38 static struct signal_handler *signal_handlers[MAX_SIGNAL_VALUE+1] = { NULL, };
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
39 static int sig_pipe_fd[2] = { -1, -1 };
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
41 static bool signals_initialized = FALSE;
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
42 static struct io *io_sig = NULL;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
43
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
44 static siginfo_t pending_signals[MAX_SIGNAL_VALUE+1];
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
45 static bool have_pending_signals = FALSE;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
46
9031
bfbbae6cdb51 Compile fix to NetBSD: Don't use si_code which is a macro.
Timo Sirainen <tss@iki.fi>
parents: 8883
diff changeset
47 const char *lib_signal_code_to_str(int signo, int sicode)
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
48 {
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
49 /* common */
9031
bfbbae6cdb51 Compile fix to NetBSD: Don't use si_code which is a macro.
Timo Sirainen <tss@iki.fi>
parents: 8883
diff changeset
50 switch (sicode) {
9816
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
51 #ifdef SI_NOINFO
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
52 case SI_NOINFO:
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
53 return "";
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
54 #endif
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
55 case SI_USER:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
56 return "kill";
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
57 #ifdef SI_KERNEL
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
58 case SI_KERNEL:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
59 return "kernel";
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
60 #endif
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
61 case SI_TIMER:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
62 return "timer";
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
63 }
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
64
9032
286ff5114588 FreeBSD compiling fix.
Timo Sirainen <tss@iki.fi>
parents: 9031
diff changeset
65 /* If SEGV_MAPERR is supported, the rest of them must be too.
286ff5114588 FreeBSD compiling fix.
Timo Sirainen <tss@iki.fi>
parents: 9031
diff changeset
66 FreeBSD 6 at least doesn't support these. */
286ff5114588 FreeBSD compiling fix.
Timo Sirainen <tss@iki.fi>
parents: 9031
diff changeset
67 #ifdef SEGV_MAPERR
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
68 switch (signo) {
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
69 case SIGSEGV:
9031
bfbbae6cdb51 Compile fix to NetBSD: Don't use si_code which is a macro.
Timo Sirainen <tss@iki.fi>
parents: 8883
diff changeset
70 switch (sicode) {
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
71 case SEGV_MAPERR:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
72 return "address not mapped";
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
73 case SEGV_ACCERR:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
74 return "invalid permissions";
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
75 }
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
76 break;
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
77 case SIGBUS:
9031
bfbbae6cdb51 Compile fix to NetBSD: Don't use si_code which is a macro.
Timo Sirainen <tss@iki.fi>
parents: 8883
diff changeset
78 switch (sicode) {
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
79 case BUS_ADRALN:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
80 return "invalid address alignment";
11445
785f1507fed8 Compile fix for OSX 10.3.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
81 #ifdef BUS_ADRERR /* for OSX 10.3 */
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
82 case BUS_ADRERR:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
83 return "nonexistent physical address";
11445
785f1507fed8 Compile fix for OSX 10.3.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
84 #endif
785f1507fed8 Compile fix for OSX 10.3.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
85 #ifdef BUS_OBJERR /* for OSX 10.3 */
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
86 case BUS_OBJERR:
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
87 return "object-specific hardware error";
11445
785f1507fed8 Compile fix for OSX 10.3.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
88 #endif
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
89 }
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
90 }
9032
286ff5114588 FreeBSD compiling fix.
Timo Sirainen <tss@iki.fi>
parents: 9031
diff changeset
91 #endif
9031
bfbbae6cdb51 Compile fix to NetBSD: Don't use si_code which is a macro.
Timo Sirainen <tss@iki.fi>
parents: 8883
diff changeset
92 return t_strdup_printf("unknown %d", sicode);
8883
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
93 }
5361cb6afe9e When a process is killed, show the signal code and the sending process's pid and uid.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
94
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
95 #ifdef SA_SIGINFO
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
96 static void sig_handler(int signo, siginfo_t *si, void *context ATTR_UNUSED)
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
97 #else
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
98 static void sig_handler(int signo)
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
99 #endif
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 {
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
101 struct signal_handler *h;
16436
fbeac7272069 Make sure errno is preserved in non-delayed signal handlers.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
102 int saved_errno;
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
103 char c = 0;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
104
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
105 #if defined(SI_NOINFO) || !defined(SA_SIGINFO)
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
106 #ifndef SA_SIGINFO
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
107 siginfo_t *si = NULL;
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
108 #endif
9816
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
109 siginfo_t tmp_si;
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
110
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
111 if (si == NULL) {
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
112 /* Solaris can leave this to NULL */
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
113 i_zero(&tmp_si);
9816
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
114 tmp_si.si_signo = signo;
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
115 tmp_si.si_code = SI_NOINFO;
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
116 si = &tmp_si;
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
117 }
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
118 #endif
11e3058af06c Solaris: Don't crash when signal handler is called with siginfo_t=NULL.
Timo Sirainen <tss@iki.fi>
parents: 9648
diff changeset
119
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
120 if (signo < 0 || signo > MAX_SIGNAL_VALUE)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
121 return;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
122
12117
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
123 if (SIGNAL_IS_TERMINAL(signo))
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
124 signal_term_counter++;
7f364dafc675 Added signal_term_counter that keeps track of how many terminal signals have been received.
Timo Sirainen <tss@iki.fi>
parents: 11445
diff changeset
125
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
126 /* remember that we're inside a signal handler which might have been
9905
54c0c2c24f2c lib-signals: Don't assert-crash with nested signal handler calls.
Timo Sirainen <tss@iki.fi>
parents: 9816
diff changeset
127 called at any time. don't do anything that's unsafe. we might also
54c0c2c24f2c lib-signals: Don't assert-crash with nested signal handler calls.
Timo Sirainen <tss@iki.fi>
parents: 9816
diff changeset
128 get interrupted by another signal while inside this handler. */
16436
fbeac7272069 Make sure errno is preserved in non-delayed signal handlers.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
129 saved_errno = errno;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
130 for (h = signal_handlers[signo]; h != NULL; h = h->next) {
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
131 if ((h->flags & LIBSIG_FLAG_DELAYED) == 0)
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
132 h->handler(si, h->context);
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
133 else if (pending_signals[signo].si_signo == 0) {
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
134 pending_signals[signo] = *si;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
135 if (!have_pending_signals) {
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
136 if (write(sig_pipe_fd[1], &c, 1) != 1)
22024
cc3d5de90348 lib: Use lib_signals_syscall_error() for write() failure in signal handler
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22023
diff changeset
137 lib_signals_syscall_error("signal: write(sigpipe) failed: ");
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
138 have_pending_signals = TRUE;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
139 }
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
140 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
141 }
16436
fbeac7272069 Make sure errno is preserved in non-delayed signal handlers.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
142 errno = saved_errno;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
143 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
144
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
145 #ifdef SA_SIGINFO
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
146 static void sig_ignore(int signo ATTR_UNUSED, siginfo_t *si ATTR_UNUSED,
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
147 void *context ATTR_UNUSED)
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
148 #else
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
149 static void sig_ignore(int signo ATTR_UNUSED)
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
150 #endif
4251
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
151 {
4252
ec4782b057f0 And s/lib_signals_ignore_signal/lib_signals_ignore/
Timo Sirainen <tss@iki.fi>
parents: 4251
diff changeset
152 /* if we used SIG_IGN instead of this function,
ec4782b057f0 And s/lib_signals_ignore_signal/lib_signals_ignore/
Timo Sirainen <tss@iki.fi>
parents: 4251
diff changeset
153 the system call might be restarted */
4251
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
154 }
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
155
14629
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
156 static void ATTR_NULL(1)
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
157 signal_read(void *context ATTR_UNUSED)
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
158 {
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
159 siginfo_t signals[MAX_SIGNAL_VALUE+1];
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
160 sigset_t fullset, oldset;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
161 struct signal_handler *h;
9905
54c0c2c24f2c lib-signals: Don't assert-crash with nested signal handler calls.
Timo Sirainen <tss@iki.fi>
parents: 9816
diff changeset
162 char buf[64];
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
163 int signo;
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
164 ssize_t ret;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
165
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
166 if (sigfillset(&fullset) < 0)
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
167 i_fatal("sigfillset() failed: %m");
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
168 if (sigprocmask(SIG_BLOCK, &fullset, &oldset) < 0)
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
169 i_fatal("sigprocmask() failed: %m");
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
170
9905
54c0c2c24f2c lib-signals: Don't assert-crash with nested signal handler calls.
Timo Sirainen <tss@iki.fi>
parents: 9816
diff changeset
171 /* typically we should read only a single byte, but if a signal
54c0c2c24f2c lib-signals: Don't assert-crash with nested signal handler calls.
Timo Sirainen <tss@iki.fi>
parents: 9816
diff changeset
172 is sent while signal handler is running we might get more. */
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
173 ret = read(sig_pipe_fd[0], buf, sizeof(buf));
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
174 if (ret > 0) {
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
175 memcpy(signals, pending_signals, sizeof(signals));
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
176 memset(pending_signals, 0, sizeof(pending_signals));
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
177 have_pending_signals = FALSE;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
178 } else if (ret < 0) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
179 if (errno != EAGAIN)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
180 i_fatal("read(sigpipe) failed: %m");
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
181 } else {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
182 i_fatal("read(sigpipe) failed: EOF");
2880
f2718224c9e9 Add signal counters to USR1 and USR2 signals too.
Timo Sirainen <tss@iki.fi>
parents: 2854
diff changeset
183 }
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
184 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
185 i_fatal("sigprocmask() failed: %m");
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
186
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
187 if (ret < 0)
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
188 return;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
189
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
190 /* call the delayed handlers after signals are copied and unblocked */
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
191 for (signo = 0; signo < MAX_SIGNAL_VALUE; signo++) {
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
192 if (signals[signo].si_signo == 0)
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
193 continue;
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
194
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
195 for (h = signal_handlers[signo]; h != NULL; h = h->next) {
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
196 if ((h->flags & LIBSIG_FLAG_DELAYED) != 0)
9648
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
197 h->handler(&signals[signo], h->context);
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
198 }
028878f7063a lib-signals: Redesigned how delayed signals are handled.
Timo Sirainen <tss@iki.fi>
parents: 9032
diff changeset
199 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
202 static void lib_signals_set(int signo, enum libsig_flags flags)
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
203 {
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
204 struct sigaction act;
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
205
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
206 if (sigemptyset(&act.sa_mask) < 0)
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
207 i_fatal("sigemptyset(): %m");
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
208 #ifdef SA_SIGINFO
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
209 act.sa_flags = SA_SIGINFO;
13063
0c6a9b907656 lib-signals: Removed unnecessary code.
Timo Sirainen <tss@iki.fi>
parents: 13022
diff changeset
210 act.sa_sigaction = sig_handler;
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
211 #else
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
212 act.sa_flags = 0;
13063
0c6a9b907656 lib-signals: Removed unnecessary code.
Timo Sirainen <tss@iki.fi>
parents: 13022
diff changeset
213 act.sa_handler = sig_handler;
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
214 #endif
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
215 if ((flags & LIBSIG_FLAG_RESTART) != 0)
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
216 act.sa_flags |= SA_RESTART;
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
217 if (sigaction(signo, &act, NULL) < 0)
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
218 i_fatal("sigaction(%d): %m", signo);
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
219 }
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
220
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
221 void lib_signals_set_handler(int signo, enum libsig_flags flags,
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
222 signal_handler_t *handler, void *context)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 {
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
224 struct signal_handler *h;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
225
4903
204d7edc7cdc Added context parameter type safety checks for most callback APIs.
Timo Sirainen <tss@iki.fi>
parents: 4824
diff changeset
226 i_assert(handler != NULL);
204d7edc7cdc Added context parameter type safety checks for most callback APIs.
Timo Sirainen <tss@iki.fi>
parents: 4824
diff changeset
227
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
228 if (signo < 0 || signo > MAX_SIGNAL_VALUE) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
229 i_panic("Trying to set signal %d handler, but max is %d",
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
230 signo, MAX_SIGNAL_VALUE);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
231 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
232
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
233 if (signal_handlers[signo] == NULL && signals_initialized)
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
234 lib_signals_set(signo, flags);
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
235
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
236 if ((flags & LIBSIG_FLAG_DELAYED) != 0 && sig_pipe_fd[0] == -1) {
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
237 /* first delayed handler */
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
238 if (pipe(sig_pipe_fd) < 0)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
239 i_fatal("pipe() failed: %m");
10493
2d7e2e76a100 lib-signals: Set signal pipe fds non-blocking to make sure read/write doesn't hang.
Timo Sirainen <tss@iki.fi>
parents: 9905
diff changeset
240 fd_set_nonblock(sig_pipe_fd[0], TRUE);
2d7e2e76a100 lib-signals: Set signal pipe fds non-blocking to make sure read/write doesn't hang.
Timo Sirainen <tss@iki.fi>
parents: 9905
diff changeset
241 fd_set_nonblock(sig_pipe_fd[1], TRUE);
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
242 fd_close_on_exec(sig_pipe_fd[0], TRUE);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
243 fd_close_on_exec(sig_pipe_fd[1], TRUE);
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
244 if (signals_initialized) {
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
245 io_sig = io_add(sig_pipe_fd[0], IO_READ,
15079
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
246 signal_read, (void *)NULL);
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
247 }
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
248 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
249
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
250 h = i_new(struct signal_handler, 1);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
251 h->handler = handler;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
252 h->context = context;
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
253 h->flags = flags;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
254
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
255 /* atomically set to signal_handlers[] list */
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
256 h->next = signal_handlers[signo];
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
257 signal_handlers[signo] = h;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259
4903
204d7edc7cdc Added context parameter type safety checks for most callback APIs.
Timo Sirainen <tss@iki.fi>
parents: 4824
diff changeset
260 void lib_signals_ignore(int signo, bool restart_syscalls)
4251
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
261 {
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
262 struct sigaction act;
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
263
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
264 if (signo < 0 || signo > MAX_SIGNAL_VALUE) {
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
265 i_panic("Trying to ignore signal %d, but max is %d",
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
266 signo, MAX_SIGNAL_VALUE);
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
267 }
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
268
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
269 i_assert(signal_handlers[signo] == NULL);
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
270
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
271 if (sigemptyset(&act.sa_mask) < 0)
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
272 i_fatal("sigemptyset(): %m");
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
273 if (restart_syscalls) {
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
274 act.sa_flags = SA_RESTART;
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
275 act.sa_handler = SIG_IGN;
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
276 } else {
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
277 #ifdef SA_SIGINFO
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
278 act.sa_flags = SA_SIGINFO;
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
279 act.sa_sigaction = sig_ignore;
10504
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
280 #else
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
281 act.sa_flags = 0;
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
282 act.sa_handler = sig_ignore;
9c2fe6d0b684 lib-signals: Compile fix for Hurd (SA_SIGINFO not available).
Timo Sirainen <tss@iki.fi>
parents: 10493
diff changeset
283 #endif
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
284 }
4251
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
285
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
286 if (sigaction(signo, &act, NULL) < 0)
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
287 i_fatal("sigaction(%d): %m", signo);
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
288 }
5bc987dc62a8 Added lib_signals_ignore_signal() and made lib_signals_set_handler() with
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
289
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
290 void lib_signals_unset_handler(int signo, signal_handler_t *handler,
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
291 void *context)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
292 {
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
293 struct signal_handler *h, **p;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
294
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
295 for (p = &signal_handlers[signo]; *p != NULL; p = &(*p)->next) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
296 if ((*p)->handler == handler && (*p)->context == context) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
297 h = *p;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
298 *p = h->next;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
299 i_free(h);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
300 return;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
301 }
2880
f2718224c9e9 Add signal counters to USR1 and USR2 signals too.
Timo Sirainen <tss@iki.fi>
parents: 2854
diff changeset
302 }
3419
b97914e7c941 Ignore SIGALRM, but not with SIG_IGN as it causes syscalls to restart.
Timo Sirainen <tss@iki.fi>
parents: 2880
diff changeset
303
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
304 i_panic("lib_signals_unset_handler(%d, %p, %p): handler not found",
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
305 signo, (void *)handler, context);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
306 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
307
8367
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
308 void lib_signals_reset_ioloop(void)
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
309 {
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
310 if (io_sig != NULL) {
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
311 io_remove(&io_sig);
15079
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
312 io_sig = io_add(sig_pipe_fd[0], IO_READ,
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
313 signal_read, (void *)NULL);
8367
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
314 }
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
315 }
0d49326397b4 Added lib_signals_reset_ioloop() for handling signals with multiple ioloops.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
316
22023
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
317 void lib_signals_syscall_error(const char *prefix)
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
318 {
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
319 /* @UNSAFE: We're in a signal handler. It's very limited what is
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
320 allowed in here. Especially strerror() isn't at least officially
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
321 allowed. */
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
322 char errno_buf[MAX_INT_STRLEN], *errno_str;
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
323 errno_str = dec2str_buf(errno_buf, errno);
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
324
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
325 size_t prefix_len = strlen(prefix);
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
326 size_t errno_str_len = strlen(errno_str);
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
327 char buf[prefix_len + errno_str_len + 1];
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
328
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
329 memcpy(buf, prefix, prefix_len);
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
330 memcpy(buf + prefix_len, errno_str, errno_str_len);
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
331 buf[prefix_len + errno_str_len] = '\n';
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
332 if (write_full(STDERR_FILENO, buf, prefix_len + errno_str_len + 1) < 0) {
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
333 /* can't really do anything */
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
334 }
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
335 }
b3897f959cb4 lib: Add lib_signals_syscall_error()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
336
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
337 void lib_signals_init(void)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
338 {
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
339 int i;
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
340
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
341 signals_initialized = TRUE;
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
342
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
343 /* add signals that were already registered */
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
344 for (i = 0; i < MAX_SIGNAL_VALUE; i++) {
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
345 if (signal_handlers[i] != NULL)
13064
86e4023d08e4 lib_signals_set_handler(): Changed API to take flags instead of boolean.
Timo Sirainen <tss@iki.fi>
parents: 13063
diff changeset
346 lib_signals_set(i, signal_handlers[i]->flags);
5815
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
347 }
3f1d268f32f0 Allow registering signal handlers even before lib_signals_init() is called.
Timo Sirainen <tss@iki.fi>
parents: 5089
diff changeset
348
15079
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
349 if (sig_pipe_fd[0] != -1) {
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
350 io_sig = io_add(sig_pipe_fd[0], IO_READ,
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
351 signal_read, (void *)NULL);
925d4a890a9b Fixed compiling with OSes where NULL isn't defined as void pointer (e.g. Solaris).
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
352 }
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
353 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
354
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
355 void lib_signals_deinit(void)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
356 {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
357 struct signal_handler *handlers, *h;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
358 int i;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
359
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
360 for (i = 0; i < MAX_SIGNAL_VALUE; i++) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
361 if (signal_handlers[i] != NULL) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
362 /* atomically remove from signal_handlers[] list */
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
363 handlers = signal_handlers[i];
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
364 signal_handlers[i] = NULL;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
365
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
366 while (handlers != NULL) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
367 h = handlers;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
368 handlers = h->next;
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
369 i_free(h);
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
370 }
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
371 }
3419
b97914e7c941 Ignore SIGALRM, but not with SIG_IGN as it causes syscalls to restart.
Timo Sirainen <tss@iki.fi>
parents: 2880
diff changeset
372 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
373
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
374 if (io_sig != NULL)
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
375 io_remove(&io_sig);
3620
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
376 if (sig_pipe_fd[0] != -1) {
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
377 if (close(sig_pipe_fd[0]) < 0)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
378 i_error("close(sigpipe) failed: %m");
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
379 if (close(sig_pipe_fd[1]) < 0)
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
380 i_error("close(sigpipe) failed: %m");
3360cc019737 Implemented new signal handling framework, which makes handling signals much
Timo Sirainen <tss@iki.fi>
parents: 3419
diff changeset
381 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
382 }