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