1*cdfa2a7eSchristos /* $NetBSD: iosignal.c,v 1.5 2020/05/25 20:47:24 christos Exp $ */
2abb0f93cSkardel
3abb0f93cSkardel /*
4abb0f93cSkardel * iosignal.c - input/output routines for ntpd. The socket-opening code
5abb0f93cSkardel * was shamelessly stolen from ntpd.
6abb0f93cSkardel */
7abb0f93cSkardel
8abb0f93cSkardel /*
9abb0f93cSkardel * [Bug 158]
10abb0f93cSkardel * Do the #includes differently, as under some versions of Linux
11abb0f93cSkardel * sys/param.h has a #undef CONFIG_PHONE line in it.
12abb0f93cSkardel *
13abb0f93cSkardel * As we have ~40 CONFIG_ variables, I don't feel like renaming them
14abb0f93cSkardel * every time somebody adds a new macro to some system header.
15abb0f93cSkardel */
16abb0f93cSkardel
17abb0f93cSkardel #ifdef HAVE_CONFIG_H
18abb0f93cSkardel # include <config.h>
19abb0f93cSkardel #endif
20abb0f93cSkardel
21abb0f93cSkardel #include <stdio.h>
22abb0f93cSkardel #include <signal.h>
23abb0f93cSkardel #ifdef HAVE_SYS_PARAM_H
24abb0f93cSkardel # include <sys/param.h>
25abb0f93cSkardel #endif /* HAVE_SYS_PARAM_H */
26abb0f93cSkardel #ifdef HAVE_SYS_IOCTL_H
27abb0f93cSkardel # include <sys/ioctl.h>
28abb0f93cSkardel #endif
29abb0f93cSkardel
30abb0f93cSkardel #include <arpa/inet.h>
31abb0f93cSkardel
32abb0f93cSkardel #if _BSDI_VERSION >= 199510
33abb0f93cSkardel # include <ifaddrs.h>
34abb0f93cSkardel #endif
35abb0f93cSkardel
36abb0f93cSkardel # ifdef __QNXNTO__
37abb0f93cSkardel # include <fcntl.h>
38abb0f93cSkardel # include <unix.h>
39abb0f93cSkardel # define FNDELAY O_NDELAY
40abb0f93cSkardel # endif
41abb0f93cSkardel
42abb0f93cSkardel #include "ntp_machine.h"
43abb0f93cSkardel #include "ntpd.h"
44abb0f93cSkardel #include "ntp_io.h"
45abb0f93cSkardel #include "ntp_if.h"
46abb0f93cSkardel #include "ntp_stdlib.h"
47abb0f93cSkardel #include "iosignal.h"
48abb0f93cSkardel
49abb0f93cSkardel #if defined(HAVE_SIGNALED_IO)
508585484eSchristos static RETSIGTYPE sigio_handler (int);
518585484eSchristos
528585484eSchristos /* consistency safegurad to catch BLOCK/UNBLOCK oversights */
53abb0f93cSkardel static int sigio_block_count = 0;
548585484eSchristos
558585484eSchristos /* main inputhandler to be called on SIGIO */
568585484eSchristos static input_handler_t *input_handler_callback = NULL;
578585484eSchristos
58abb0f93cSkardel # if defined(HAVE_SIGACTION)
59abb0f93cSkardel /*
60abb0f93cSkardel * If sigaction() is used for signal handling and a signal is
61abb0f93cSkardel * pending then the kernel blocks the signal before it calls
62abb0f93cSkardel * the signal handler.
63abb0f93cSkardel *
64abb0f93cSkardel * The variable below is used to take care that the SIGIO signal
65abb0f93cSkardel * is not unintentionally unblocked inside the sigio_handler()
66abb0f93cSkardel * if the handler executes a piece of code that is normally
67abb0f93cSkardel * bracketed by BLOCKIO()/UNBLOCKIO() calls.
68abb0f93cSkardel */
69abb0f93cSkardel static int sigio_handler_active = 0;
70abb0f93cSkardel # endif
71abb0f93cSkardel
72abb0f93cSkardel /*
73abb0f93cSkardel * SIGPOLL and SIGIO ROUTINES.
74abb0f93cSkardel */
75abb0f93cSkardel
76abb0f93cSkardel
77abb0f93cSkardel
78abb0f93cSkardel /*
79abb0f93cSkardel * TTY initialization routines.
80abb0f93cSkardel */
81abb0f93cSkardel int
init_clock_sig(struct refclockio * rio)82abb0f93cSkardel init_clock_sig(
83abb0f93cSkardel struct refclockio *rio
84abb0f93cSkardel )
85abb0f93cSkardel {
86abb0f93cSkardel # ifdef USE_TTY_SIGPOLL
87abb0f93cSkardel {
88abb0f93cSkardel /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
89abb0f93cSkardel if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
90abb0f93cSkardel {
91abb0f93cSkardel msyslog(LOG_ERR,
92abb0f93cSkardel "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
93abb0f93cSkardel return 1;
94abb0f93cSkardel }
95abb0f93cSkardel return 0;
96abb0f93cSkardel }
97abb0f93cSkardel # else
98abb0f93cSkardel /*
99abb0f93cSkardel * Special cases first!
100abb0f93cSkardel */
101abb0f93cSkardel /* Was: defined(SYS_HPUX) */
102abb0f93cSkardel # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
103abb0f93cSkardel #define CLOCK_DONE
104abb0f93cSkardel {
105abb0f93cSkardel int pgrp, on = 1;
106abb0f93cSkardel
107abb0f93cSkardel /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
108abb0f93cSkardel pgrp = getpid();
109abb0f93cSkardel if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
110abb0f93cSkardel {
1118585484eSchristos msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m - EXITING");
112abb0f93cSkardel exit(1);
113abb0f93cSkardel /*NOTREACHED*/
114abb0f93cSkardel }
115abb0f93cSkardel
116abb0f93cSkardel /*
117abb0f93cSkardel * set non-blocking, async I/O on the descriptor
118abb0f93cSkardel */
119abb0f93cSkardel if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
120abb0f93cSkardel {
1218585484eSchristos msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m - EXITING");
122abb0f93cSkardel exit(1);
123abb0f93cSkardel /*NOTREACHED*/
124abb0f93cSkardel }
125abb0f93cSkardel
126abb0f93cSkardel if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
127abb0f93cSkardel {
1288585484eSchristos msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m - EXITING");
129abb0f93cSkardel exit(1);
130abb0f93cSkardel /*NOTREACHED*/
131abb0f93cSkardel }
132abb0f93cSkardel return 0;
133abb0f93cSkardel }
134abb0f93cSkardel # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
135abb0f93cSkardel /* Was: defined(SYS_AIX) && !defined(_BSD) */
136abb0f93cSkardel # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
137abb0f93cSkardel /*
138abb0f93cSkardel * SYSV compatibility mode under AIX.
139abb0f93cSkardel */
140abb0f93cSkardel #define CLOCK_DONE
141abb0f93cSkardel {
142abb0f93cSkardel int pgrp, on = 1;
143abb0f93cSkardel
144abb0f93cSkardel /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
145abb0f93cSkardel if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
146abb0f93cSkardel {
147abb0f93cSkardel msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
148abb0f93cSkardel return 1;
149abb0f93cSkardel }
150abb0f93cSkardel pgrp = -getpid();
151abb0f93cSkardel if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
152abb0f93cSkardel {
153abb0f93cSkardel msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
154abb0f93cSkardel return 1;
155abb0f93cSkardel }
156abb0f93cSkardel
157abb0f93cSkardel if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
158abb0f93cSkardel {
159abb0f93cSkardel msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
160abb0f93cSkardel return 1;
161abb0f93cSkardel }
162abb0f93cSkardel return 0;
163abb0f93cSkardel }
164abb0f93cSkardel # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
165abb0f93cSkardel # ifndef CLOCK_DONE
166abb0f93cSkardel {
167abb0f93cSkardel /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
168abb0f93cSkardel # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
169abb0f93cSkardel /*
170abb0f93cSkardel * there are, however, always exceptions to the rules
171abb0f93cSkardel * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
172abb0f93cSkardel * CTTYs. SunOS and HPUX do not semm to have this restriction.
173abb0f93cSkardel * another question is: how can you do multiple SIGIO from several
174abb0f93cSkardel * ttys (as they all should be CTTYs), wondering...
175abb0f93cSkardel *
176abb0f93cSkardel * kd 95-07-16
177abb0f93cSkardel */
178abb0f93cSkardel if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
179abb0f93cSkardel {
180abb0f93cSkardel msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
181abb0f93cSkardel return 1;
182abb0f93cSkardel }
183abb0f93cSkardel # endif /* TIOCSCTTY && USE_FSETOWNCTTY */
184abb0f93cSkardel
185abb0f93cSkardel if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
186abb0f93cSkardel {
187abb0f93cSkardel msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
188abb0f93cSkardel return 1;
189abb0f93cSkardel }
190abb0f93cSkardel
191abb0f93cSkardel if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
192abb0f93cSkardel {
193abb0f93cSkardel msyslog(LOG_ERR,
194abb0f93cSkardel "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
195abb0f93cSkardel return 1;
196abb0f93cSkardel }
197abb0f93cSkardel return 0;
198abb0f93cSkardel }
199abb0f93cSkardel # endif /* CLOCK_DONE */
200abb0f93cSkardel # endif /* !USE_TTY_SIGPOLL */
201abb0f93cSkardel }
202abb0f93cSkardel
203abb0f93cSkardel
204abb0f93cSkardel
205abb0f93cSkardel void
init_socket_sig(int fd)206abb0f93cSkardel init_socket_sig(
207abb0f93cSkardel int fd
208abb0f93cSkardel )
209abb0f93cSkardel {
210abb0f93cSkardel # ifdef USE_UDP_SIGPOLL
211abb0f93cSkardel {
212abb0f93cSkardel if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
213abb0f93cSkardel {
214abb0f93cSkardel msyslog(LOG_ERR,
2158585484eSchristos "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m - EXITING");
216abb0f93cSkardel exit(1);
217abb0f93cSkardel }
218abb0f93cSkardel }
219abb0f93cSkardel # else /* USE_UDP_SIGPOLL */
220abb0f93cSkardel {
221abb0f93cSkardel int pgrp;
222abb0f93cSkardel # ifdef FIOASYNC
223abb0f93cSkardel int on = 1;
224abb0f93cSkardel # endif
225abb0f93cSkardel
226abb0f93cSkardel # if defined(FIOASYNC)
227abb0f93cSkardel if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
228abb0f93cSkardel {
2298585484eSchristos msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m - EXITING");
230abb0f93cSkardel exit(1);
231abb0f93cSkardel /*NOTREACHED*/
232abb0f93cSkardel }
233abb0f93cSkardel # elif defined(FASYNC)
234abb0f93cSkardel {
235abb0f93cSkardel int flags;
236abb0f93cSkardel
237abb0f93cSkardel if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
238abb0f93cSkardel {
2398585484eSchristos msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m - EXITING");
240abb0f93cSkardel exit(1);
241abb0f93cSkardel /*NOTREACHED*/
242abb0f93cSkardel }
243abb0f93cSkardel if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
244abb0f93cSkardel {
2458585484eSchristos msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m - EXITING");
246abb0f93cSkardel exit(1);
247abb0f93cSkardel /*NOTREACHED*/
248abb0f93cSkardel }
249abb0f93cSkardel }
250abb0f93cSkardel # else
251abb0f93cSkardel # include "Bletch: Need asynchronous I/O!"
252abb0f93cSkardel # endif
253abb0f93cSkardel
254abb0f93cSkardel # ifdef UDP_BACKWARDS_SETOWN
255abb0f93cSkardel pgrp = -getpid();
256abb0f93cSkardel # else
257abb0f93cSkardel pgrp = getpid();
258abb0f93cSkardel # endif
259abb0f93cSkardel
260abb0f93cSkardel # if defined(SIOCSPGRP)
261abb0f93cSkardel if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
262abb0f93cSkardel {
2638585484eSchristos msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m - EXITING");
264abb0f93cSkardel exit(1);
265abb0f93cSkardel /*NOTREACHED*/
266abb0f93cSkardel }
267abb0f93cSkardel # elif defined(FIOSETOWN)
268abb0f93cSkardel if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
269abb0f93cSkardel {
2708585484eSchristos msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m - EXITING");
271abb0f93cSkardel exit(1);
272abb0f93cSkardel /*NOTREACHED*/
273abb0f93cSkardel }
274abb0f93cSkardel # elif defined(F_SETOWN)
275abb0f93cSkardel if (fcntl(fd, F_SETOWN, pgrp) == -1)
276abb0f93cSkardel {
2778585484eSchristos msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m - EXITING");
278abb0f93cSkardel exit(1);
279abb0f93cSkardel /*NOTREACHED*/
280abb0f93cSkardel }
281abb0f93cSkardel # else
282abb0f93cSkardel # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
283abb0f93cSkardel # endif
284abb0f93cSkardel }
285abb0f93cSkardel # endif /* USE_UDP_SIGPOLL */
286abb0f93cSkardel }
287abb0f93cSkardel
2888585484eSchristos static RETSIGTYPE
sigio_handler(int sig)289abb0f93cSkardel sigio_handler(
290abb0f93cSkardel int sig
291abb0f93cSkardel )
292abb0f93cSkardel {
293abb0f93cSkardel int saved_errno = errno;
294abb0f93cSkardel l_fp ts;
295abb0f93cSkardel
296abb0f93cSkardel get_systime(&ts);
297abb0f93cSkardel
298abb0f93cSkardel # if defined(HAVE_SIGACTION)
299abb0f93cSkardel sigio_handler_active++;
300abb0f93cSkardel if (sigio_handler_active != 1) /* This should never happen! */
301abb0f93cSkardel msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1");
302abb0f93cSkardel # endif
303abb0f93cSkardel
3048585484eSchristos INSIST(input_handler_callback != NULL);
3058585484eSchristos (*input_handler_callback)(&ts);
306abb0f93cSkardel
307abb0f93cSkardel # if defined(HAVE_SIGACTION)
308abb0f93cSkardel sigio_handler_active--;
309abb0f93cSkardel if (sigio_handler_active != 0) /* This should never happen! */
310abb0f93cSkardel msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0");
311abb0f93cSkardel # endif
312abb0f93cSkardel
313abb0f93cSkardel errno = saved_errno;
314abb0f93cSkardel }
315abb0f93cSkardel
316abb0f93cSkardel /*
317abb0f93cSkardel * Signal support routines.
318abb0f93cSkardel */
319abb0f93cSkardel # ifdef HAVE_SIGACTION
320abb0f93cSkardel void
set_signal(input_handler_t * input)3218585484eSchristos set_signal(input_handler_t *input)
322abb0f93cSkardel {
3238585484eSchristos INSIST(input != NULL);
3248585484eSchristos
3258585484eSchristos input_handler_callback = input;
3268585484eSchristos
3278585484eSchristos using_sigio = TRUE;
328abb0f93cSkardel # ifdef USE_SIGIO
329abb0f93cSkardel (void) signal_no_reset(SIGIO, sigio_handler);
330abb0f93cSkardel # endif
331abb0f93cSkardel # ifdef USE_SIGPOLL
332abb0f93cSkardel (void) signal_no_reset(SIGPOLL, sigio_handler);
333abb0f93cSkardel # endif
334abb0f93cSkardel }
335abb0f93cSkardel
336abb0f93cSkardel void
block_io_and_alarm(void)337abb0f93cSkardel block_io_and_alarm(void)
338abb0f93cSkardel {
339abb0f93cSkardel sigset_t set;
340abb0f93cSkardel
341abb0f93cSkardel if (sigemptyset(&set))
342abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
343abb0f93cSkardel # if defined(USE_SIGIO)
344abb0f93cSkardel if (sigaddset(&set, SIGIO))
345abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
346abb0f93cSkardel # endif
347abb0f93cSkardel # if defined(USE_SIGPOLL)
348abb0f93cSkardel if (sigaddset(&set, SIGPOLL))
349abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
350abb0f93cSkardel # endif
351abb0f93cSkardel if (sigaddset(&set, SIGALRM))
352abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
353abb0f93cSkardel
354abb0f93cSkardel if (sigprocmask(SIG_BLOCK, &set, NULL))
355abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
356abb0f93cSkardel }
357abb0f93cSkardel
358abb0f93cSkardel void
block_sigio(void)359abb0f93cSkardel block_sigio(void)
360abb0f93cSkardel {
361abb0f93cSkardel if ( sigio_handler_active == 0 ) /* not called from within signal handler */
362abb0f93cSkardel {
363abb0f93cSkardel sigset_t set;
364abb0f93cSkardel
365abb0f93cSkardel ++sigio_block_count;
366abb0f93cSkardel if (sigio_block_count > 1)
367abb0f93cSkardel msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
368abb0f93cSkardel if (sigio_block_count < 1)
369abb0f93cSkardel msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
370abb0f93cSkardel
371abb0f93cSkardel if (sigemptyset(&set))
372abb0f93cSkardel msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
373abb0f93cSkardel # if defined(USE_SIGIO)
374abb0f93cSkardel if (sigaddset(&set, SIGIO))
375abb0f93cSkardel msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
376abb0f93cSkardel # endif
377abb0f93cSkardel # if defined(USE_SIGPOLL)
378abb0f93cSkardel if (sigaddset(&set, SIGPOLL))
379abb0f93cSkardel msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
380abb0f93cSkardel # endif
381abb0f93cSkardel
382abb0f93cSkardel if (sigprocmask(SIG_BLOCK, &set, NULL))
383abb0f93cSkardel msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
384abb0f93cSkardel }
385abb0f93cSkardel }
386abb0f93cSkardel
387abb0f93cSkardel void
unblock_io_and_alarm(void)388abb0f93cSkardel unblock_io_and_alarm(void)
389abb0f93cSkardel {
390abb0f93cSkardel sigset_t unset;
391abb0f93cSkardel
392abb0f93cSkardel if (sigemptyset(&unset))
393abb0f93cSkardel msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
394abb0f93cSkardel
395abb0f93cSkardel # if defined(USE_SIGIO)
396abb0f93cSkardel if (sigaddset(&unset, SIGIO))
397abb0f93cSkardel msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
398abb0f93cSkardel # endif
399abb0f93cSkardel # if defined(USE_SIGPOLL)
400abb0f93cSkardel if (sigaddset(&unset, SIGPOLL))
401abb0f93cSkardel msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
402abb0f93cSkardel # endif
403abb0f93cSkardel if (sigaddset(&unset, SIGALRM))
404abb0f93cSkardel msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
405abb0f93cSkardel
406abb0f93cSkardel if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
407abb0f93cSkardel msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
408abb0f93cSkardel }
409abb0f93cSkardel
410abb0f93cSkardel void
unblock_sigio(void)411abb0f93cSkardel unblock_sigio(void)
412abb0f93cSkardel {
413abb0f93cSkardel if ( sigio_handler_active == 0 ) /* not called from within signal handler */
414abb0f93cSkardel {
415abb0f93cSkardel sigset_t unset;
416abb0f93cSkardel
417abb0f93cSkardel --sigio_block_count;
418abb0f93cSkardel if (sigio_block_count > 0)
419abb0f93cSkardel msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
420abb0f93cSkardel if (sigio_block_count < 0)
421abb0f93cSkardel msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
422abb0f93cSkardel
423abb0f93cSkardel if (sigemptyset(&unset))
424abb0f93cSkardel msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
425abb0f93cSkardel
426abb0f93cSkardel # if defined(USE_SIGIO)
427abb0f93cSkardel if (sigaddset(&unset, SIGIO))
428abb0f93cSkardel msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
429abb0f93cSkardel # endif
430abb0f93cSkardel # if defined(USE_SIGPOLL)
431abb0f93cSkardel if (sigaddset(&unset, SIGPOLL))
432abb0f93cSkardel msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
433abb0f93cSkardel # endif
434abb0f93cSkardel
435abb0f93cSkardel if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
436abb0f93cSkardel msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
437abb0f93cSkardel }
438abb0f93cSkardel }
439abb0f93cSkardel
440abb0f93cSkardel void
wait_for_signal(void)441abb0f93cSkardel wait_for_signal(void)
442abb0f93cSkardel {
443abb0f93cSkardel sigset_t old;
444abb0f93cSkardel
445abb0f93cSkardel if (sigprocmask(SIG_UNBLOCK, NULL, &old))
446abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
447abb0f93cSkardel
448abb0f93cSkardel # if defined(USE_SIGIO)
449abb0f93cSkardel if (sigdelset(&old, SIGIO))
450abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
451abb0f93cSkardel # endif
452abb0f93cSkardel # if defined(USE_SIGPOLL)
453abb0f93cSkardel if (sigdelset(&old, SIGPOLL))
454abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
455abb0f93cSkardel # endif
456abb0f93cSkardel if (sigdelset(&old, SIGALRM))
457abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
458abb0f93cSkardel
459abb0f93cSkardel if (sigsuspend(&old) && (errno != EINTR))
460abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
461abb0f93cSkardel }
462abb0f93cSkardel
463abb0f93cSkardel # else /* !HAVE_SIGACTION */
464abb0f93cSkardel /*
465abb0f93cSkardel * Must be an old bsd system.
466abb0f93cSkardel * We assume there is no SIGPOLL.
467abb0f93cSkardel */
468abb0f93cSkardel
469abb0f93cSkardel void
block_io_and_alarm(void)470abb0f93cSkardel block_io_and_alarm(void)
471abb0f93cSkardel {
472abb0f93cSkardel int mask;
473abb0f93cSkardel
474abb0f93cSkardel mask = sigmask(SIGIO) | sigmask(SIGALRM);
475abb0f93cSkardel if (sigblock(mask))
476abb0f93cSkardel msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
477abb0f93cSkardel }
478abb0f93cSkardel
479abb0f93cSkardel void
block_sigio(void)480abb0f93cSkardel block_sigio(void)
481abb0f93cSkardel {
482abb0f93cSkardel int mask;
483abb0f93cSkardel
484abb0f93cSkardel ++sigio_block_count;
485abb0f93cSkardel if (sigio_block_count > 1)
486abb0f93cSkardel msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
487abb0f93cSkardel if (sigio_block_count < 1)
488abb0f93cSkardel msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
489abb0f93cSkardel
490abb0f93cSkardel mask = sigmask(SIGIO);
491abb0f93cSkardel if (sigblock(mask))
492abb0f93cSkardel msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
493abb0f93cSkardel }
494abb0f93cSkardel
495abb0f93cSkardel void
set_signal(input_handler_t * input)4968585484eSchristos set_signal(input_handler_t *input)
497abb0f93cSkardel {
4988585484eSchristos INSIST(input != NULL);
4998585484eSchristos
5008585484eSchristos input_handler_callback = input;
5018585484eSchristos
5028585484eSchristos using_sigio = TRUE;
503abb0f93cSkardel (void) signal_no_reset(SIGIO, sigio_handler);
504abb0f93cSkardel }
505abb0f93cSkardel
506abb0f93cSkardel void
unblock_io_and_alarm(void)507abb0f93cSkardel unblock_io_and_alarm(void)
508abb0f93cSkardel {
509abb0f93cSkardel int mask, omask;
510abb0f93cSkardel
511abb0f93cSkardel mask = sigmask(SIGIO) | sigmask(SIGALRM);
512abb0f93cSkardel omask = sigblock(0);
513abb0f93cSkardel omask &= ~mask;
514abb0f93cSkardel (void) sigsetmask(omask);
515abb0f93cSkardel }
516abb0f93cSkardel
517abb0f93cSkardel void
unblock_sigio(void)518abb0f93cSkardel unblock_sigio(void)
519abb0f93cSkardel {
520abb0f93cSkardel int mask, omask;
521abb0f93cSkardel
522abb0f93cSkardel --sigio_block_count;
523abb0f93cSkardel if (sigio_block_count > 0)
524abb0f93cSkardel msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
525abb0f93cSkardel if (sigio_block_count < 0)
526abb0f93cSkardel msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
527abb0f93cSkardel mask = sigmask(SIGIO);
528abb0f93cSkardel omask = sigblock(0);
529abb0f93cSkardel omask &= ~mask;
530abb0f93cSkardel (void) sigsetmask(omask);
531abb0f93cSkardel }
532abb0f93cSkardel
533abb0f93cSkardel void
wait_for_signal(void)534abb0f93cSkardel wait_for_signal(void)
535abb0f93cSkardel {
536abb0f93cSkardel int mask, omask;
537abb0f93cSkardel
538abb0f93cSkardel mask = sigmask(SIGIO) | sigmask(SIGALRM);
539abb0f93cSkardel omask = sigblock(0);
540abb0f93cSkardel omask &= ~mask;
541abb0f93cSkardel if (sigpause(omask) && (errno != EINTR))
542abb0f93cSkardel msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
543abb0f93cSkardel }
544abb0f93cSkardel
545abb0f93cSkardel # endif /* HAVE_SIGACTION */
546abb0f93cSkardel #else
547abb0f93cSkardel int NotAnEmptyCompilationUnit;
548abb0f93cSkardel #endif
549