summaryrefslogtreecommitdiffstats
path: root/src/lib/lib-signals.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/lib-signals.h72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/lib/lib-signals.h b/src/lib/lib-signals.h
new file mode 100644
index 0000000..d491de7
--- /dev/null
+++ b/src/lib/lib-signals.h
@@ -0,0 +1,72 @@
+#ifndef LIB_SIGNALS_H
+#define LIB_SIGNALS_H
+
+#include <signal.h>
+
+enum libsig_flags {
+ /* Signal handler will be called later from IO loop when it's safe to
+ do any kind of work */
+ LIBSIG_FLAG_DELAYED = 0x01,
+ /* Restart syscalls instead of having them fail with EINTR */
+ LIBSIG_FLAG_RESTART = 0x02,
+ /* Automatically shift delayed signal handling for this signal
+ to a newly started ioloop. */
+ LIBSIG_FLAG_IOLOOP_AUTOMOVE = 0x04,
+};
+#define LIBSIG_FLAGS_SAFE (LIBSIG_FLAG_DELAYED | LIBSIG_FLAG_RESTART)
+
+typedef void signal_handler_t(const siginfo_t *si, void *context);
+
+/* Number of times a "termination signal" has been received.
+ These signals are SIGINT, SIGQUIT and SIGTERM. Callers can compare this to
+ their saved previous value to see if a syscall returning EINTR should be
+ treated as someone wanting to end the process or just some internal signal
+ that should be ignored, such as SIGCHLD.
+
+ This is marked as volatile so that compiler won't optimize away its
+ comparisons. It may not work perfectly everywhere, such as when accessing it
+ isn't atomic, so you shouldn't heavily rely on its actual value. */
+extern volatile unsigned int signal_term_counter;
+
+/* Convert si_code to string */
+const char *lib_signal_code_to_str(int signo, int sicode);
+
+/* Detach IOs from all ioloops. This isn't normally necessary, except when
+ forking a process. */
+void lib_signals_ioloop_detach(void);
+void lib_signals_ioloop_attach(void);
+
+/* Set signal handler for specific signal. */
+void lib_signals_set_handler(int signo, enum libsig_flags flags,
+ signal_handler_t *handler, void *context)
+ ATTR_NULL(4);
+/* 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
+ ignored. */
+void lib_signals_clear_handlers_and_ignore(int signo);
+/* Unset specific signal handler for specific signal. */
+void lib_signals_unset_handler(int signo,
+ signal_handler_t *handler, void *context)
+ ATTR_NULL(3);
+
+/* Indicate whether signals are expected for the indicated delayed handler. When
+ signals are expected, the io for delayed handlers will be allowed to wait
+ alone on the ioloop. */
+void lib_signals_set_expected(int signo, bool expected,
+ signal_handler_t *handler, void *context);
+ ATTR_NULL(4);
+
+/* Switch ioloop for a specific signal handler created with
+ LIBSIG_FLAG_NO_IOLOOP_AUTOMOVE. */
+void lib_signals_switch_ioloop(int signo,
+ signal_handler_t *handler, void *context);
+
+/* 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);
+
+void lib_signals_init(void);
+void lib_signals_deinit(void);
+
+#endif