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