return t_strdup_printf("unknown %d", sicode);
}
-static void lib_signal_delayed(const siginfo_t *si)
+void lib_signal_delayed(const siginfo_t *si)
{
int signo = si->si_signo;
void lib_signals_set_handler(int signo, enum libsig_flags flags,
signal_handler_t *handler, void *context)
+{
+ if ((flags & LIBSIG_FLAG_DELAYED) == 0)
+ lib_signals_set_handler2(signo, flags, handler, NULL, context);
+ else
+ lib_signals_set_handler2(signo, flags, NULL, handler, context);
+}
+
+void lib_signals_set_handler2(int signo, enum libsig_flags flags,
+ signal_handler_t *immediate_handler,
+ signal_handler_t *delayed_handler,
+ void *context)
{
struct signal_handler *h;
- i_assert(handler != NULL);
+ i_assert(immediate_handler != NULL || delayed_handler != NULL);
if (signo < 0 || signo > MAX_SIGNAL_VALUE) {
i_panic("Trying to set signal %d handler, but max is %d",
lib_signals_set(signo, flags);
h = i_new(struct signal_handler, 1);
- if ((flags & LIBSIG_FLAG_DELAYED) == 0)
- h->immediate_handler = handler;
- else
- h->delayed_handler = handler;
+ h->immediate_handler = immediate_handler;
+ h->delayed_handler = delayed_handler;
h->context = context;
h->flags = flags;
void lib_signals_set_handler(int signo, enum libsig_flags flags,
signal_handler_t *handler, void *context)
ATTR_NULL(4);
+/* Set the immediate_handler to be called always. If the handler calls
+ lib_signals_delayed(), call also delayed_handler later.
+ The LIBSIG_FLAG_DELAYED flag is ignored. */
+void lib_signals_set_handler2(int signo, enum libsig_flags flags,
+ signal_handler_t *immediate_handler,
+ signal_handler_t *delayed_handler,
+ void *context)
+ ATTR_NULL(5);
/* Ignore given signal. */
void lib_signals_ignore(int signo, bool restart_syscalls);
/* Clear all signal handlers for a specific signal and set the signal to be
/* Log a syscall error inside a (non-delayed) signal handler where i_error() is
unsafe. errno number will be appended to the prefix. */
void lib_signals_syscall_error(const char *prefix);
+/* Call the delayed signal handler later for the given signal. This is expected
+ to be called from an immediate signal handler set by
+ lib_signals_set_handler2(). */
+void lib_signal_delayed(const siginfo_t *si);
void lib_signals_init(void);
void lib_signals_deinit(void);