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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include "ntp_syslog.h"
#include "ntp_stdlib.h"
static ctrl_c_fn ctrl_c_hook;
#ifndef SYS_WINNT
RETSIGTYPE sigint_handler(int);
#else
BOOL WINAPI console_event_handler(DWORD);
#endif
#ifdef HAVE_SIGACTION
# ifdef SA_RESTART
# define Z_SA_RESTART SA_RESTART
# else
# define Z_SA_RESTART 0
# endif
void
signal_no_reset(
int sig,
void (*func)(int)
)
{
int n;
struct sigaction vec;
struct sigaction ovec;
ZERO(vec);
sigemptyset(&vec.sa_mask);
vec.sa_handler = func;
/* Added for PPS clocks on Solaris 7 which get EINTR errors */
# ifdef SIGPOLL
if (SIGPOLL == sig)
vec.sa_flags = Z_SA_RESTART;
# endif
# ifdef SIGIO
if (SIGIO == sig)
vec.sa_flags = Z_SA_RESTART;
# endif
do
n = sigaction(sig, &vec, &ovec);
while (-1 == n && EINTR == errno);
if (-1 == n) {
perror("sigaction");
exit(1);
}
}
#elif HAVE_SIGVEC
void
signal_no_reset(
int sig,
RETSIGTYPE (*func)(int)
)
{
struct sigvec sv;
int n;
ZERO(sv);
sv.sv_handler = func;
n = sigvec(sig, &sv, (struct sigvec *)NULL);
if (-1 == n) {
perror("sigvec");
exit(1);
}
}
#elif HAVE_SIGSET
void
signal_no_reset(
int sig,
RETSIGTYPE (*func)(int)
)
{
int n;
n = sigset(sig, func);
if (-1 == n) {
perror("sigset");
exit(1);
}
}
#else
/* Beware! This implementation resets the signal to SIG_DFL */
void
signal_no_reset(
int sig,
RETSIGTYPE (*func)(int)
)
{
#ifndef SIG_ERR
# define SIG_ERR (-1)
#endif
if (SIG_ERR == signal(sig, func)) {
perror("signal");
exit(1);
}
}
#endif
#ifndef SYS_WINNT
/*
* POSIX implementation of set_ctrl_c_hook()
*/
RETSIGTYPE
sigint_handler(
int signum
)
{
UNUSED_ARG(signum);
if (ctrl_c_hook != NULL)
(*ctrl_c_hook)();
}
void
set_ctrl_c_hook(
ctrl_c_fn c_hook
)
{
RETSIGTYPE (*handler)(int);
if (NULL == c_hook) {
handler = SIG_DFL;
signal_no_reset(SIGINT, handler);
ctrl_c_hook = c_hook;
} else {
ctrl_c_hook = c_hook;
handler = &sigint_handler;
signal_no_reset(SIGINT, handler);
}
}
#else /* SYS_WINNT follows */
/*
* Windows implementation of set_ctrl_c_hook()
*/
BOOL WINAPI
console_event_handler(
DWORD dwCtrlType
)
{
BOOL handled;
if (CTRL_C_EVENT == dwCtrlType && ctrl_c_hook != NULL) {
(*ctrl_c_hook)();
handled = TRUE;
} else {
handled = FALSE;
}
return handled;
}
void
set_ctrl_c_hook(
ctrl_c_fn c_hook
)
{
BOOL install;
if (NULL == c_hook) {
ctrl_c_hook = NULL;
install = FALSE;
} else {
ctrl_c_hook = c_hook;
install = TRUE;
}
if (!SetConsoleCtrlHandler(&console_event_handler, install))
msyslog(LOG_ERR, "Can't %s console control handler: %m",
(install)
? "add"
: "remove");
}
#endif /* SYS_WINNT */
|