← Back to davo.co
aboutsummaryrefslogtreecommitdiffstats
path: root/sighandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'sighandler.h')
-rw-r--r--sighandler.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/sighandler.h b/sighandler.h
new file mode 100644
index 0000000..4b7768d
--- /dev/null
+++ b/sighandler.h
@@ -0,0 +1,101 @@
+#ifndef SIGHANDLER_H
+#define SIGHANDLER_H 1
+
+#include "c23-fallback.h"
+#include <stdio.h>
+#ifndef __STDC_NO_ATOMIC__
+# include <stdatomic.h>
+#endif
+
+/**
+ ** @brief A pair of strings to hold signal information
+ **/
+struct sh_pair {
+ char const* name;
+ char const* desc;
+};
+typedef struct sh_pair sh_pair;
+
+/**
+ ** @brief For each possible signal, this holds a pair of strings with
+ ** signal information.
+ **
+ ** The size of this array can be queried with `sh_known`.
+ **
+ ** @see SH_PRINT to use that information.
+ **
+ ** Conditionally, this also adds some commonly used extensions.
+ **/
+extern sh_pair const sh_pairs[];
+
+extern size_t const sh_known;
+
+#if ATOMIC_LONG_LOCK_FREE > 1
+/**
+ ** @brief Keep track of the number of calls into a
+ ** signal handler for each possible signal.
+ **
+ ** Don't use this array directly.
+ **
+ ** @see sh_count to update this information.
+ ** @see SH_PRINT to use that information.
+ **/
+extern _Atomic(unsigned long) sh_counts[];
+
+/**
+ ** @brief Use this in your signal handler to keep track of the
+ ** number of calls to the signal @a sig.
+ **
+ ** @see sh_counted to use that information.
+ **/
+inline
+void sh_count(int sig) {
+ if (sig < sh_known) ++sh_counts[sig];
+}
+
+inline
+unsigned long sh_counted(int sig){
+ return (sig < sh_known) ? sh_counts[sig] : 0;
+}
+
+#else
+inline
+void sh_count(int sig) {
+ // empty
+}
+
+inline
+unsigned long sh_counted(int sig){
+ return 0;
+}
+#endif
+
+/**
+ ** @brief Prototype of signal handlers
+ **/
+typedef void sh_handler(int);
+
+/**
+ ** @brief Pretty-prints signal information
+ **
+ ** @see PRINT_SIG for a convenient user interface
+ **/
+void sh_print(FILE* io, int sig,
+ char const* filename, size_t line,
+ char const* string);
+
+/**
+ ** @brief Pretty-prints signal information
+ **
+ ** This prints signal information @a STRING for signal @a SIG to
+ ** stream @a IO.
+ **/
+#define SH_PRINT(IO, SIG, STRING) sh_print(IO, SIG, __FILE__, __LINE__, STRING)
+
+/**
+ ** @brief Enables a signal handler and catches the errors
+ **/
+sh_handler* sh_enable(int sig, sh_handler* hnd);
+
+
+#endif