]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: lib-signals - Add lib_signals_set_handler2() to set both immediate/delayed handlers
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 2 Feb 2022 18:41:16 +0000 (19:41 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Sun, 13 Feb 2022 10:23:26 +0000 (10:23 +0000)
src/lib/lib-signals.c
src/lib/lib-signals.h

index af7f91dc912c732c7f81a08e354e49de03ee55c5..2adcb524d5f15c257f28606e55f93280fb56334f 100644 (file)
@@ -111,7 +111,7 @@ const char *lib_signal_code_to_str(int signo, int sicode)
        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;
 
@@ -499,10 +499,21 @@ static void lib_signals_set(int signo, enum libsig_flags flags)
 
 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",
@@ -513,10 +524,8 @@ void lib_signals_set_handler(int signo, enum libsig_flags flags,
                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;
 
index d491de74c317bb2283b8ec2dc9c1aba2df97a112..2042efe8d0536812c16bf8f2c824c5839637aa2c 100644 (file)
@@ -40,6 +40,14 @@ void lib_signals_ioloop_attach(void);
 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
@@ -65,6 +73,10 @@ void lib_signals_switch_ioloop(int signo,
 /* 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);