/src/ntp-dev/libntp/syssignal.c
Line | Count | Source (jump to first uncovered line) |
1 | | #ifdef HAVE_CONFIG_H |
2 | | # include <config.h> |
3 | | #endif |
4 | | |
5 | | #include <stdio.h> |
6 | | #include <sys/types.h> |
7 | | #include <signal.h> |
8 | | |
9 | | #include "ntp_syslog.h" |
10 | | #include "ntp_stdlib.h" |
11 | | |
12 | | static ctrl_c_fn ctrl_c_hook; |
13 | | #ifndef SYS_WINNT |
14 | | RETSIGTYPE sigint_handler(int); |
15 | | #else |
16 | | BOOL WINAPI console_event_handler(DWORD); |
17 | | #endif |
18 | | |
19 | | |
20 | | #ifdef HAVE_SIGACTION |
21 | | |
22 | | # ifdef SA_RESTART |
23 | 0 | # define Z_SA_RESTART SA_RESTART |
24 | | # else |
25 | | # define Z_SA_RESTART 0 |
26 | | # endif |
27 | | |
28 | | void |
29 | | signal_no_reset( |
30 | | int sig, |
31 | | void (*func)(int) |
32 | | ) |
33 | 1 | { |
34 | 1 | int n; |
35 | 1 | struct sigaction vec; |
36 | 1 | struct sigaction ovec; |
37 | | |
38 | 1 | ZERO(vec); |
39 | 1 | sigemptyset(&vec.sa_mask); |
40 | 1 | vec.sa_handler = func; |
41 | | |
42 | | /* Added for PPS clocks on Solaris 7 which get EINTR errors */ |
43 | 1 | # ifdef SIGPOLL |
44 | 1 | if (SIGPOLL == sig) |
45 | 0 | vec.sa_flags = Z_SA_RESTART; |
46 | 1 | # endif |
47 | 1 | # ifdef SIGIO |
48 | 1 | if (SIGIO == sig) |
49 | 0 | vec.sa_flags = Z_SA_RESTART; |
50 | 1 | # endif |
51 | | |
52 | 1 | do |
53 | 1 | n = sigaction(sig, &vec, &ovec); |
54 | 1 | while (-1 == n && EINTR == errno); |
55 | 1 | if (-1 == n) { |
56 | 0 | perror("sigaction"); |
57 | 0 | exit(1); |
58 | 0 | } |
59 | 1 | } |
60 | | |
61 | | #elif HAVE_SIGVEC |
62 | | |
63 | | void |
64 | | signal_no_reset( |
65 | | int sig, |
66 | | RETSIGTYPE (*func)(int) |
67 | | ) |
68 | | { |
69 | | struct sigvec sv; |
70 | | int n; |
71 | | |
72 | | ZERO(sv); |
73 | | sv.sv_handler = func; |
74 | | n = sigvec(sig, &sv, (struct sigvec *)NULL); |
75 | | if (-1 == n) { |
76 | | perror("sigvec"); |
77 | | exit(1); |
78 | | } |
79 | | } |
80 | | |
81 | | #elif HAVE_SIGSET |
82 | | |
83 | | void |
84 | | signal_no_reset( |
85 | | int sig, |
86 | | RETSIGTYPE (*func)(int) |
87 | | ) |
88 | | { |
89 | | int n; |
90 | | |
91 | | n = sigset(sig, func); |
92 | | if (-1 == n) { |
93 | | perror("sigset"); |
94 | | exit(1); |
95 | | } |
96 | | } |
97 | | |
98 | | #else |
99 | | |
100 | | /* Beware! This implementation resets the signal to SIG_DFL */ |
101 | | void |
102 | | signal_no_reset( |
103 | | int sig, |
104 | | RETSIGTYPE (*func)(int) |
105 | | ) |
106 | | { |
107 | | #ifndef SIG_ERR |
108 | | # define SIG_ERR (-1) |
109 | | #endif |
110 | | if (SIG_ERR == signal(sig, func)) { |
111 | | perror("signal"); |
112 | | exit(1); |
113 | | } |
114 | | } |
115 | | |
116 | | #endif |
117 | | |
118 | | #ifndef SYS_WINNT |
119 | | /* |
120 | | * POSIX implementation of set_ctrl_c_hook() |
121 | | */ |
122 | | RETSIGTYPE |
123 | | sigint_handler( |
124 | | int signum |
125 | | ) |
126 | 0 | { |
127 | 0 | UNUSED_ARG(signum); |
128 | 0 | if (ctrl_c_hook != NULL) |
129 | 0 | (*ctrl_c_hook)(); |
130 | 0 | } |
131 | | |
132 | | void |
133 | | set_ctrl_c_hook( |
134 | | ctrl_c_fn c_hook |
135 | | ) |
136 | 0 | { |
137 | 0 | RETSIGTYPE (*handler)(int); |
138 | |
|
139 | 0 | if (NULL == c_hook) { |
140 | 0 | handler = SIG_DFL; |
141 | 0 | signal_no_reset(SIGINT, handler); |
142 | 0 | ctrl_c_hook = c_hook; |
143 | 0 | } else { |
144 | 0 | ctrl_c_hook = c_hook; |
145 | 0 | handler = &sigint_handler; |
146 | 0 | signal_no_reset(SIGINT, handler); |
147 | 0 | } |
148 | 0 | } |
149 | | #else /* SYS_WINNT follows */ |
150 | | /* |
151 | | * Windows implementation of set_ctrl_c_hook() |
152 | | */ |
153 | | BOOL WINAPI |
154 | | console_event_handler( |
155 | | DWORD dwCtrlType |
156 | | ) |
157 | | { |
158 | | BOOL handled; |
159 | | |
160 | | if (CTRL_C_EVENT == dwCtrlType && ctrl_c_hook != NULL) { |
161 | | (*ctrl_c_hook)(); |
162 | | handled = TRUE; |
163 | | } else { |
164 | | handled = FALSE; |
165 | | } |
166 | | |
167 | | return handled; |
168 | | } |
169 | | void |
170 | | set_ctrl_c_hook( |
171 | | ctrl_c_fn c_hook |
172 | | ) |
173 | | { |
174 | | BOOL install; |
175 | | |
176 | | if (NULL == c_hook) { |
177 | | ctrl_c_hook = NULL; |
178 | | install = FALSE; |
179 | | } else { |
180 | | ctrl_c_hook = c_hook; |
181 | | install = TRUE; |
182 | | } |
183 | | if (!SetConsoleCtrlHandler(&console_event_handler, install)) |
184 | | msyslog(LOG_ERR, "Can't %s console control handler: %m", |
185 | | (install) |
186 | | ? "add" |
187 | | : "remove"); |
188 | | } |
189 | | #endif /* SYS_WINNT */ |