Coverage Report

Created: 2023-05-19 06:16

/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 */