1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
|