xref: /freebsd/contrib/ntp/libntp/iosignal.c (revision 224ba2bd37e182b64f7d78defef8a6cacaad3415)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * ntp_io.c - input/output routines for ntpd.	The socket-opening code
3c0b746e5SOllivier Robert  *		   was shamelessly stolen from ntpd.
4c0b746e5SOllivier Robert  */
5c0b746e5SOllivier Robert 
6224ba2bdSOllivier Robert #include "ntp_machine.h"
7c0b746e5SOllivier Robert #include "ntpd.h"
8c0b746e5SOllivier Robert #include "ntp_io.h"
9c0b746e5SOllivier Robert #include "ntp_if.h"
10c0b746e5SOllivier Robert #include "ntp_stdlib.h"
11c0b746e5SOllivier Robert #include "iosignal.h"
12c0b746e5SOllivier Robert 
13224ba2bdSOllivier Robert #include <stdio.h>
14224ba2bdSOllivier Robert #include <signal.h>
15224ba2bdSOllivier Robert #ifdef HAVE_SYS_PARAM_H
16224ba2bdSOllivier Robert # include <sys/param.h>
17224ba2bdSOllivier Robert #endif /* HAVE_SYS_PARAM_H */
18224ba2bdSOllivier Robert #ifdef HAVE_SYS_IOCTL_H
19224ba2bdSOllivier Robert # include <sys/ioctl.h>
20224ba2bdSOllivier Robert #endif
21224ba2bdSOllivier Robert 
22224ba2bdSOllivier Robert #include <arpa/inet.h>
23224ba2bdSOllivier Robert 
24224ba2bdSOllivier Robert #if _BSDI_VERSION >= 199510
25224ba2bdSOllivier Robert # include <ifaddrs.h>
26224ba2bdSOllivier Robert #endif
27224ba2bdSOllivier Robert 
28c0b746e5SOllivier Robert #if defined(HAVE_SIGNALED_IO)
29c0b746e5SOllivier Robert static int sigio_block_count = 0;
30c0b746e5SOllivier Robert extern	void	input_handler	P((l_fp *));
31c0b746e5SOllivier Robert 
32c0b746e5SOllivier Robert /*
33c0b746e5SOllivier Robert  * SIGPOLL and SIGIO ROUTINES.
34c0b746e5SOllivier Robert  */
35c0b746e5SOllivier Robert 
36c0b746e5SOllivier Robert  /*
37c0b746e5SOllivier Robert  * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
38c0b746e5SOllivier Robert  * a few have separate SIGIO and SIGPOLL signals.  This code checks for the
39c0b746e5SOllivier Robert  * SIGIO == SIGPOLL case at compile time.
40c0b746e5SOllivier Robert  * Do not defined USE_SIGPOLL or USE_SIGIO.
41c0b746e5SOllivier Robert  * these are interal only to ntp_io.c!
42c0b746e5SOllivier Robert  */
43c0b746e5SOllivier Robert # if defined(USE_SIGPOLL)
44c0b746e5SOllivier Robert #  undef USE_SIGPOLL
45c0b746e5SOllivier Robert # endif
46c0b746e5SOllivier Robert # if defined(USE_SIGIO)
47c0b746e5SOllivier Robert #  undef USE_SIGIO
48c0b746e5SOllivier Robert # endif
49c0b746e5SOllivier Robert 
50c0b746e5SOllivier Robert # if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
51c0b746e5SOllivier Robert #  define USE_SIGPOLL
52c0b746e5SOllivier Robert # endif
53c0b746e5SOllivier Robert 
54c0b746e5SOllivier Robert # if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
55c0b746e5SOllivier Robert #  define USE_SIGIO
56c0b746e5SOllivier Robert # endif
57c0b746e5SOllivier Robert 
58c0b746e5SOllivier Robert # if defined(USE_SIGIO) && defined(USE_SIGPOLL)
59c0b746e5SOllivier Robert #  if SIGIO == SIGPOLL
60c0b746e5SOllivier Robert #	define USE_SIGIO
61c0b746e5SOllivier Robert #	undef USE_SIGPOLL
62c0b746e5SOllivier Robert #  endif /* SIGIO == SIGPOLL */
63c0b746e5SOllivier Robert # endif /* USE_SIGIO && USE_SIGIO */
64c0b746e5SOllivier Robert 
65c0b746e5SOllivier Robert 
66c0b746e5SOllivier Robert /*
67c0b746e5SOllivier Robert  * TTY initialization routines.
68c0b746e5SOllivier Robert  */
69c0b746e5SOllivier Robert int
70c0b746e5SOllivier Robert init_clock_sig(
71c0b746e5SOllivier Robert 	struct refclockio *rio
72c0b746e5SOllivier Robert 	)
73c0b746e5SOllivier Robert {
74c0b746e5SOllivier Robert # ifdef USE_TTY_SIGPOLL
75c0b746e5SOllivier Robert 	{
76c0b746e5SOllivier Robert 		/* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
77c0b746e5SOllivier Robert 		if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
78c0b746e5SOllivier Robert 		{
79c0b746e5SOllivier Robert 			msyslog(LOG_ERR,
80c0b746e5SOllivier Robert 				"init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
81c0b746e5SOllivier Robert 			return 1;
82c0b746e5SOllivier Robert 		}
83c0b746e5SOllivier Robert 		return 0;
84c0b746e5SOllivier Robert 	}
85c0b746e5SOllivier Robert # else
86c0b746e5SOllivier Robert 	/*
87c0b746e5SOllivier Robert 	 * Special cases first!
88c0b746e5SOllivier Robert 	 */
89c0b746e5SOllivier Robert 	/* Was: defined(SYS_HPUX) */
90c0b746e5SOllivier Robert #  if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
91c0b746e5SOllivier Robert #define CLOCK_DONE
92c0b746e5SOllivier Robert 	{
93c0b746e5SOllivier Robert 		int pgrp, on = 1;
94c0b746e5SOllivier Robert 
95c0b746e5SOllivier Robert 		/* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
96c0b746e5SOllivier Robert 		pgrp = getpid();
97c0b746e5SOllivier Robert 		if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
98c0b746e5SOllivier Robert 		{
99c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
100c0b746e5SOllivier Robert 			exit(1);
101c0b746e5SOllivier Robert 			/*NOTREACHED*/
102c0b746e5SOllivier Robert 		}
103c0b746e5SOllivier Robert 
104c0b746e5SOllivier Robert 		/*
105c0b746e5SOllivier Robert 		 * set non-blocking, async I/O on the descriptor
106c0b746e5SOllivier Robert 		 */
107c0b746e5SOllivier Robert 		if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
108c0b746e5SOllivier Robert 		{
109c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
110c0b746e5SOllivier Robert 			exit(1);
111c0b746e5SOllivier Robert 			/*NOTREACHED*/
112c0b746e5SOllivier Robert 		}
113c0b746e5SOllivier Robert 
114c0b746e5SOllivier Robert 		if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
115c0b746e5SOllivier Robert 		{
116c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
117c0b746e5SOllivier Robert 			exit(1);
118c0b746e5SOllivier Robert 			/*NOTREACHED*/
119c0b746e5SOllivier Robert 		}
120c0b746e5SOllivier Robert 		return 0;
121c0b746e5SOllivier Robert 	}
122c0b746e5SOllivier Robert #  endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
123c0b746e5SOllivier Robert 	/* Was: defined(SYS_AIX) && !defined(_BSD) */
124c0b746e5SOllivier Robert #  if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
125c0b746e5SOllivier Robert 	/*
126c0b746e5SOllivier Robert 	 * SYSV compatibility mode under AIX.
127c0b746e5SOllivier Robert 	 */
128c0b746e5SOllivier Robert #define CLOCK_DONE
129c0b746e5SOllivier Robert 	{
130c0b746e5SOllivier Robert 		int pgrp, on = 1;
131c0b746e5SOllivier Robert 
132c0b746e5SOllivier Robert 		/* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
133c0b746e5SOllivier Robert 		if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
134c0b746e5SOllivier Robert 		{
135c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
136c0b746e5SOllivier Robert 			return 1;
137c0b746e5SOllivier Robert 		}
138c0b746e5SOllivier Robert 		pgrp = -getpid();
139c0b746e5SOllivier Robert 		if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
140c0b746e5SOllivier Robert 		{
141c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
142c0b746e5SOllivier Robert 			return 1;
143c0b746e5SOllivier Robert 		}
144c0b746e5SOllivier Robert 
145c0b746e5SOllivier Robert 		if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
146c0b746e5SOllivier Robert 		{
147c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
148c0b746e5SOllivier Robert 			return 1;
149c0b746e5SOllivier Robert 		}
150c0b746e5SOllivier Robert 		return 0;
151c0b746e5SOllivier Robert 	}
152c0b746e5SOllivier Robert #  endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
153c0b746e5SOllivier Robert #  ifndef  CLOCK_DONE
154c0b746e5SOllivier Robert 	{
155c0b746e5SOllivier Robert 		/* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
156c0b746e5SOllivier Robert #	if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
157c0b746e5SOllivier Robert 		/*
158c0b746e5SOllivier Robert 		 * there are, however, always exceptions to the rules
159c0b746e5SOllivier Robert 		 * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
160c0b746e5SOllivier Robert 		 * CTTYs. SunOS and HPUX do not semm to have this restriction.
161c0b746e5SOllivier Robert 		 * another question is: how can you do multiple SIGIO from several
162c0b746e5SOllivier Robert 		 * ttys (as they all should be CTTYs), wondering...
163c0b746e5SOllivier Robert 		 *
164c0b746e5SOllivier Robert 		 * kd 95-07-16
165c0b746e5SOllivier Robert 		 */
166c0b746e5SOllivier Robert 		if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
167c0b746e5SOllivier Robert 		{
168c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
169c0b746e5SOllivier Robert 			return 1;
170c0b746e5SOllivier Robert 		}
171c0b746e5SOllivier Robert #	endif /* TIOCSCTTY && USE_FSETOWNCTTY */
172c0b746e5SOllivier Robert 
173c0b746e5SOllivier Robert 		if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
174c0b746e5SOllivier Robert 		{
175c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
176c0b746e5SOllivier Robert 			return 1;
177c0b746e5SOllivier Robert 		}
178c0b746e5SOllivier Robert 
179c0b746e5SOllivier Robert 		if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
180c0b746e5SOllivier Robert 		{
181c0b746e5SOllivier Robert 			msyslog(LOG_ERR,
182c0b746e5SOllivier Robert 				"fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
183c0b746e5SOllivier Robert 			return 1;
184c0b746e5SOllivier Robert 		}
185c0b746e5SOllivier Robert 		return 0;
186c0b746e5SOllivier Robert 	}
187c0b746e5SOllivier Robert #  endif /* CLOCK_DONE */
188c0b746e5SOllivier Robert # endif /* !USE_TTY_SIGPOLL  */
189c0b746e5SOllivier Robert }
190c0b746e5SOllivier Robert 
191c0b746e5SOllivier Robert 
192c0b746e5SOllivier Robert 
193c0b746e5SOllivier Robert void
194c0b746e5SOllivier Robert init_socket_sig(
195c0b746e5SOllivier Robert 	int fd
196c0b746e5SOllivier Robert 	)
197c0b746e5SOllivier Robert {
198c0b746e5SOllivier Robert # ifdef USE_UDP_SIGPOLL
199c0b746e5SOllivier Robert 	{
200c0b746e5SOllivier Robert 		if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
201c0b746e5SOllivier Robert 		{
202c0b746e5SOllivier Robert 			msyslog(LOG_ERR,
203c0b746e5SOllivier Robert 				"init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
204c0b746e5SOllivier Robert 			exit(1);
205c0b746e5SOllivier Robert 		}
206c0b746e5SOllivier Robert 	}
207c0b746e5SOllivier Robert # else /* USE_UDP_SIGPOLL */
208c0b746e5SOllivier Robert 	{
209c0b746e5SOllivier Robert 		int pgrp;
210c0b746e5SOllivier Robert # ifdef FIOASYNC
211c0b746e5SOllivier Robert 		int on = 1;
212c0b746e5SOllivier Robert # endif
213c0b746e5SOllivier Robert 
214c0b746e5SOllivier Robert #  if defined(FIOASYNC)
215c0b746e5SOllivier Robert 		if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
216c0b746e5SOllivier Robert 		{
217c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
218c0b746e5SOllivier Robert 			exit(1);
219c0b746e5SOllivier Robert 			/*NOTREACHED*/
220c0b746e5SOllivier Robert 		}
221c0b746e5SOllivier Robert #  elif defined(FASYNC)
222c0b746e5SOllivier Robert 		{
223c0b746e5SOllivier Robert 			int flags;
224c0b746e5SOllivier Robert 
225c0b746e5SOllivier Robert 			if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
226c0b746e5SOllivier Robert 			{
227c0b746e5SOllivier Robert 				msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
228c0b746e5SOllivier Robert 				exit(1);
229c0b746e5SOllivier Robert 				/*NOTREACHED*/
230c0b746e5SOllivier Robert 			}
231c0b746e5SOllivier Robert 			if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
232c0b746e5SOllivier Robert 			{
233c0b746e5SOllivier Robert 				msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
234c0b746e5SOllivier Robert 				exit(1);
235c0b746e5SOllivier Robert 				/*NOTREACHED*/
236c0b746e5SOllivier Robert 			}
237c0b746e5SOllivier Robert 		}
238c0b746e5SOllivier Robert #  else
239c0b746e5SOllivier Robert #	include "Bletch: Need asynchronous I/O!"
240c0b746e5SOllivier Robert #  endif
241c0b746e5SOllivier Robert 
242c0b746e5SOllivier Robert #  ifdef UDP_BACKWARDS_SETOWN
243c0b746e5SOllivier Robert 		pgrp = -getpid();
244c0b746e5SOllivier Robert #  else
245c0b746e5SOllivier Robert 		pgrp = getpid();
246c0b746e5SOllivier Robert #  endif
247c0b746e5SOllivier Robert 
248c0b746e5SOllivier Robert #  if defined(SIOCSPGRP)
249c0b746e5SOllivier Robert 		if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
250c0b746e5SOllivier Robert 		{
251c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
252c0b746e5SOllivier Robert 			exit(1);
253c0b746e5SOllivier Robert 			/*NOTREACHED*/
254c0b746e5SOllivier Robert 		}
255c0b746e5SOllivier Robert #  elif defined(FIOSETOWN)
256c0b746e5SOllivier Robert 		if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
257c0b746e5SOllivier Robert 		{
258c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
259c0b746e5SOllivier Robert 			exit(1);
260c0b746e5SOllivier Robert 			/*NOTREACHED*/
261c0b746e5SOllivier Robert 		}
262c0b746e5SOllivier Robert #  elif defined(F_SETOWN)
263c0b746e5SOllivier Robert 		if (fcntl(fd, F_SETOWN, pgrp) == -1)
264c0b746e5SOllivier Robert 		{
265c0b746e5SOllivier Robert 			msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
266c0b746e5SOllivier Robert 			exit(1);
267c0b746e5SOllivier Robert 			/*NOTREACHED*/
268c0b746e5SOllivier Robert 		}
269c0b746e5SOllivier Robert #  else
270c0b746e5SOllivier Robert #	include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
271c0b746e5SOllivier Robert #  endif
272c0b746e5SOllivier Robert 	}
273c0b746e5SOllivier Robert # endif /* USE_UDP_SIGPOLL */
274c0b746e5SOllivier Robert }
275c0b746e5SOllivier Robert 
276c0b746e5SOllivier Robert RETSIGTYPE
277c0b746e5SOllivier Robert sigio_handler(
278c0b746e5SOllivier Robert 	int sig
279c0b746e5SOllivier Robert 	)
280c0b746e5SOllivier Robert {
281c0b746e5SOllivier Robert 	int saved_errno = errno;
282c0b746e5SOllivier Robert 	l_fp ts;
283c0b746e5SOllivier Robert 
284c0b746e5SOllivier Robert 	get_systime(&ts);
285c0b746e5SOllivier Robert 	(void)input_handler(&ts);
286c0b746e5SOllivier Robert 	errno = saved_errno;
287c0b746e5SOllivier Robert }
288c0b746e5SOllivier Robert 
289c0b746e5SOllivier Robert /*
290c0b746e5SOllivier Robert  * Signal support routines.
291c0b746e5SOllivier Robert  */
292c0b746e5SOllivier Robert # ifdef HAVE_SIGACTION
293c0b746e5SOllivier Robert void
294c0b746e5SOllivier Robert set_signal(void)
295c0b746e5SOllivier Robert {
296c0b746e5SOllivier Robert #  ifdef USE_SIGIO
297c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGIO, sigio_handler);
298c0b746e5SOllivier Robert # endif
299c0b746e5SOllivier Robert #  ifdef USE_SIGPOLL
300c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGPOLL, sigio_handler);
301c0b746e5SOllivier Robert # endif
302c0b746e5SOllivier Robert }
303c0b746e5SOllivier Robert 
304c0b746e5SOllivier Robert void
305c0b746e5SOllivier Robert block_io_and_alarm(void)
306c0b746e5SOllivier Robert {
307c0b746e5SOllivier Robert 	sigset_t set;
308c0b746e5SOllivier Robert 
309c0b746e5SOllivier Robert 	if (sigemptyset(&set))
310c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
311c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
312c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGIO))
313c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
314c0b746e5SOllivier Robert #  endif
315c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
316c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGPOLL))
317c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
318c0b746e5SOllivier Robert #  endif
319c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGALRM))
320c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
321c0b746e5SOllivier Robert 
322c0b746e5SOllivier Robert 	if (sigprocmask(SIG_BLOCK, &set, NULL))
323c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
324c0b746e5SOllivier Robert }
325c0b746e5SOllivier Robert 
326c0b746e5SOllivier Robert void
327c0b746e5SOllivier Robert block_sigio(void)
328c0b746e5SOllivier Robert {
329c0b746e5SOllivier Robert 	sigset_t set;
330c0b746e5SOllivier Robert 
331c0b746e5SOllivier Robert 	++sigio_block_count;
332c0b746e5SOllivier Robert 	if (sigio_block_count > 1)
333c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
334c0b746e5SOllivier Robert 	if (sigio_block_count < 1)
335c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
336c0b746e5SOllivier Robert 
337c0b746e5SOllivier Robert 	if (sigemptyset(&set))
338c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
339c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
340c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGIO))
341c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
342c0b746e5SOllivier Robert #  endif
343c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
344c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGPOLL))
345c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
346c0b746e5SOllivier Robert #  endif
347c0b746e5SOllivier Robert 
348c0b746e5SOllivier Robert 	if (sigprocmask(SIG_BLOCK, &set, NULL))
349c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
350c0b746e5SOllivier Robert }
351c0b746e5SOllivier Robert 
352c0b746e5SOllivier Robert void
353c0b746e5SOllivier Robert unblock_io_and_alarm(void)
354c0b746e5SOllivier Robert {
355c0b746e5SOllivier Robert 	sigset_t unset;
356c0b746e5SOllivier Robert 
357c0b746e5SOllivier Robert 	if (sigemptyset(&unset))
358c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
359c0b746e5SOllivier Robert 
360c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
361c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGIO))
362c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
363c0b746e5SOllivier Robert #  endif
364c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
365c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGPOLL))
366c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
367c0b746e5SOllivier Robert #  endif
368c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGALRM))
369c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
370c0b746e5SOllivier Robert 
371c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
372c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
373c0b746e5SOllivier Robert }
374c0b746e5SOllivier Robert 
375c0b746e5SOllivier Robert void
376c0b746e5SOllivier Robert unblock_sigio(void)
377c0b746e5SOllivier Robert {
378c0b746e5SOllivier Robert 	sigset_t unset;
379c0b746e5SOllivier Robert 
380c0b746e5SOllivier Robert 	--sigio_block_count;
381c0b746e5SOllivier Robert 	if (sigio_block_count > 0)
382c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
383c0b746e5SOllivier Robert 	if (sigio_block_count < 0)
384c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
385c0b746e5SOllivier Robert 
386c0b746e5SOllivier Robert 	if (sigemptyset(&unset))
387c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
388c0b746e5SOllivier Robert 
389c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
390c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGIO))
391c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
392c0b746e5SOllivier Robert #  endif
393c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
394c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGPOLL))
395c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
396c0b746e5SOllivier Robert #  endif
397c0b746e5SOllivier Robert 
398c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
399c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
400c0b746e5SOllivier Robert }
401c0b746e5SOllivier Robert 
402c0b746e5SOllivier Robert void
403c0b746e5SOllivier Robert wait_for_signal(void)
404c0b746e5SOllivier Robert {
405c0b746e5SOllivier Robert 	sigset_t old;
406c0b746e5SOllivier Robert 
407c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, NULL, &old))
408c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
409c0b746e5SOllivier Robert 
410c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
411c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGIO))
412c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
413c0b746e5SOllivier Robert #  endif
414c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
415c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGPOLL))
416c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
417c0b746e5SOllivier Robert #  endif
418c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGALRM))
419c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
420c0b746e5SOllivier Robert 
421c0b746e5SOllivier Robert 	if (sigsuspend(&old) && (errno != EINTR))
422c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
423c0b746e5SOllivier Robert }
424c0b746e5SOllivier Robert 
425c0b746e5SOllivier Robert # else /* !HAVE_SIGACTION */
426c0b746e5SOllivier Robert /*
427c0b746e5SOllivier Robert  * Must be an old bsd system.
428c0b746e5SOllivier Robert  * We assume there is no SIGPOLL.
429c0b746e5SOllivier Robert  */
430c0b746e5SOllivier Robert 
431c0b746e5SOllivier Robert void
432c0b746e5SOllivier Robert block_io_and_alarm(void)
433c0b746e5SOllivier Robert {
434c0b746e5SOllivier Robert 	int mask;
435c0b746e5SOllivier Robert 
436c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
437c0b746e5SOllivier Robert 	if (sigblock(mask))
438c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
439c0b746e5SOllivier Robert }
440c0b746e5SOllivier Robert 
441c0b746e5SOllivier Robert void
442c0b746e5SOllivier Robert block_sigio(void)
443c0b746e5SOllivier Robert {
444c0b746e5SOllivier Robert 	int mask;
445c0b746e5SOllivier Robert 
446c0b746e5SOllivier Robert 	++sigio_block_count;
447c0b746e5SOllivier Robert 	if (sigio_block_count > 1)
448c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
449c0b746e5SOllivier Robert 	if (sigio_block_count < 1)
450c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
451c0b746e5SOllivier Robert 
452c0b746e5SOllivier Robert 	mask = sigmask(SIGIO);
453c0b746e5SOllivier Robert 	if (sigblock(mask))
454c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
455c0b746e5SOllivier Robert }
456c0b746e5SOllivier Robert 
457c0b746e5SOllivier Robert void
458c0b746e5SOllivier Robert set_signal(void)
459c0b746e5SOllivier Robert {
460c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGIO, sigio_handler);
461c0b746e5SOllivier Robert }
462c0b746e5SOllivier Robert 
463c0b746e5SOllivier Robert void
464c0b746e5SOllivier Robert unblock_io_and_alarm(void)
465c0b746e5SOllivier Robert {
466c0b746e5SOllivier Robert 	int mask, omask;
467c0b746e5SOllivier Robert 
468c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
469c0b746e5SOllivier Robert 	omask = sigblock(0);
470c0b746e5SOllivier Robert 	omask &= ~mask;
471c0b746e5SOllivier Robert 	(void) sigsetmask(omask);
472c0b746e5SOllivier Robert }
473c0b746e5SOllivier Robert 
474c0b746e5SOllivier Robert void
475c0b746e5SOllivier Robert unblock_sigio(void)
476c0b746e5SOllivier Robert {
477c0b746e5SOllivier Robert 	int mask, omask;
478c0b746e5SOllivier Robert 
479c0b746e5SOllivier Robert 	--sigio_block_count;
480c0b746e5SOllivier Robert 	if (sigio_block_count > 0)
481c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
482c0b746e5SOllivier Robert 	if (sigio_block_count < 0)
483c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
484c0b746e5SOllivier Robert 	mask = sigmask(SIGIO);
485c0b746e5SOllivier Robert 	omask = sigblock(0);
486c0b746e5SOllivier Robert 	omask &= ~mask;
487c0b746e5SOllivier Robert 	(void) sigsetmask(omask);
488c0b746e5SOllivier Robert }
489c0b746e5SOllivier Robert 
490c0b746e5SOllivier Robert void
491c0b746e5SOllivier Robert wait_for_signal(void)
492c0b746e5SOllivier Robert {
493c0b746e5SOllivier Robert 	int mask, omask;
494c0b746e5SOllivier Robert 
495c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
496c0b746e5SOllivier Robert 	omask = sigblock(0);
497c0b746e5SOllivier Robert 	omask &= ~mask;
498c0b746e5SOllivier Robert 	if (sigpause(omask) && (errno != EINTR))
499c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
500c0b746e5SOllivier Robert }
501c0b746e5SOllivier Robert 
502c0b746e5SOllivier Robert # endif /* HAVE_SIGACTION */
503c0b746e5SOllivier Robert #else
504c0b746e5SOllivier Robert int  NotAnEmptyCompilationUnit;
505c0b746e5SOllivier Robert #endif
506