xref: /freebsd/contrib/ntp/libntp/iosignal.c (revision c0b746e5e8d9479f05b3749cbf1f73b8928719bd)
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 
6c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H
7c0b746e5SOllivier Robert # include <config.h>
8c0b746e5SOllivier Robert #endif
9c0b746e5SOllivier Robert 
10c0b746e5SOllivier Robert #include <stdio.h>
11c0b746e5SOllivier Robert #include <signal.h>
12c0b746e5SOllivier Robert #include <sys/types.h>
13c0b746e5SOllivier Robert #ifdef HAVE_SYS_PARAM_H
14c0b746e5SOllivier Robert # include <sys/param.h>
15c0b746e5SOllivier Robert #endif /* HAVE_SYS_PARAM_H */
16c0b746e5SOllivier Robert #ifdef HAVE_SYS_TIME_H
17c0b746e5SOllivier Robert # include <sys/time.h>
18c0b746e5SOllivier Robert #endif
19c0b746e5SOllivier Robert #ifdef HAVE_NETINET_IN_H
20c0b746e5SOllivier Robert # include <netinet/in.h>
21c0b746e5SOllivier Robert #endif
22c0b746e5SOllivier Robert #ifdef HAVE_SYS_IOCTL_H
23c0b746e5SOllivier Robert # include <sys/ioctl.h>
24c0b746e5SOllivier Robert #endif
25c0b746e5SOllivier Robert #ifdef HAVE_SYS_SOCKIO_H	/* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
26c0b746e5SOllivier Robert # include <sys/sockio.h>
27c0b746e5SOllivier Robert #endif
28c0b746e5SOllivier Robert #include <arpa/inet.h>
29c0b746e5SOllivier Robert 
30c0b746e5SOllivier Robert #if _BSDI_VERSION >= 199510
31c0b746e5SOllivier Robert # include <ifaddrs.h>
32c0b746e5SOllivier Robert #endif
33c0b746e5SOllivier Robert /*	98/06/01  */
34c0b746e5SOllivier Robert #include "ntp_machine.h"	/*  98/06/01  */
35c0b746e5SOllivier Robert #include "ntpd.h"
36c0b746e5SOllivier Robert #include "ntp_io.h"
37c0b746e5SOllivier Robert #include "ntp_if.h"
38c0b746e5SOllivier Robert #include "ntp_stdlib.h"
39c0b746e5SOllivier Robert #include "iosignal.h"
40c0b746e5SOllivier Robert 
41c0b746e5SOllivier Robert #if defined(HAVE_SIGNALED_IO)
42c0b746e5SOllivier Robert static int sigio_block_count = 0;
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);
298c0b746e5SOllivier Robert 	(void)input_handler(&ts);
299c0b746e5SOllivier Robert 	errno = saved_errno;
300c0b746e5SOllivier Robert }
301c0b746e5SOllivier Robert 
302c0b746e5SOllivier Robert /*
303c0b746e5SOllivier Robert  * Signal support routines.
304c0b746e5SOllivier Robert  */
305c0b746e5SOllivier Robert # ifdef HAVE_SIGACTION
306c0b746e5SOllivier Robert void
307c0b746e5SOllivier Robert set_signal(void)
308c0b746e5SOllivier Robert {
309c0b746e5SOllivier Robert #  ifdef USE_SIGIO
310c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGIO, sigio_handler);
311c0b746e5SOllivier Robert # endif
312c0b746e5SOllivier Robert #  ifdef USE_SIGPOLL
313c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGPOLL, sigio_handler);
314c0b746e5SOllivier Robert # endif
315c0b746e5SOllivier Robert }
316c0b746e5SOllivier Robert 
317c0b746e5SOllivier Robert void
318c0b746e5SOllivier Robert block_io_and_alarm(void)
319c0b746e5SOllivier Robert {
320c0b746e5SOllivier Robert 	sigset_t set;
321c0b746e5SOllivier Robert 
322c0b746e5SOllivier Robert 	if (sigemptyset(&set))
323c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
324c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
325c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGIO))
326c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
327c0b746e5SOllivier Robert #  endif
328c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
329c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGPOLL))
330c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
331c0b746e5SOllivier Robert #  endif
332c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGALRM))
333c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
334c0b746e5SOllivier Robert 
335c0b746e5SOllivier Robert 	if (sigprocmask(SIG_BLOCK, &set, NULL))
336c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
337c0b746e5SOllivier Robert }
338c0b746e5SOllivier Robert 
339c0b746e5SOllivier Robert void
340c0b746e5SOllivier Robert block_sigio(void)
341c0b746e5SOllivier Robert {
342c0b746e5SOllivier Robert 	sigset_t set;
343c0b746e5SOllivier Robert 
344c0b746e5SOllivier Robert 	++sigio_block_count;
345c0b746e5SOllivier Robert 	if (sigio_block_count > 1)
346c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
347c0b746e5SOllivier Robert 	if (sigio_block_count < 1)
348c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
349c0b746e5SOllivier Robert 
350c0b746e5SOllivier Robert 	if (sigemptyset(&set))
351c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
352c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
353c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGIO))
354c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
355c0b746e5SOllivier Robert #  endif
356c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
357c0b746e5SOllivier Robert 	if (sigaddset(&set, SIGPOLL))
358c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
359c0b746e5SOllivier Robert #  endif
360c0b746e5SOllivier Robert 
361c0b746e5SOllivier Robert 	if (sigprocmask(SIG_BLOCK, &set, NULL))
362c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
363c0b746e5SOllivier Robert }
364c0b746e5SOllivier Robert 
365c0b746e5SOllivier Robert void
366c0b746e5SOllivier Robert unblock_io_and_alarm(void)
367c0b746e5SOllivier Robert {
368c0b746e5SOllivier Robert 	sigset_t unset;
369c0b746e5SOllivier Robert 
370c0b746e5SOllivier Robert 	if (sigemptyset(&unset))
371c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
372c0b746e5SOllivier Robert 
373c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
374c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGIO))
375c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
376c0b746e5SOllivier Robert #  endif
377c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
378c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGPOLL))
379c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
380c0b746e5SOllivier Robert #  endif
381c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGALRM))
382c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
383c0b746e5SOllivier Robert 
384c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
385c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
386c0b746e5SOllivier Robert }
387c0b746e5SOllivier Robert 
388c0b746e5SOllivier Robert void
389c0b746e5SOllivier Robert unblock_sigio(void)
390c0b746e5SOllivier Robert {
391c0b746e5SOllivier Robert 	sigset_t unset;
392c0b746e5SOllivier Robert 
393c0b746e5SOllivier Robert 	--sigio_block_count;
394c0b746e5SOllivier Robert 	if (sigio_block_count > 0)
395c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
396c0b746e5SOllivier Robert 	if (sigio_block_count < 0)
397c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
398c0b746e5SOllivier Robert 
399c0b746e5SOllivier Robert 	if (sigemptyset(&unset))
400c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
401c0b746e5SOllivier Robert 
402c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
403c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGIO))
404c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
405c0b746e5SOllivier Robert #  endif
406c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
407c0b746e5SOllivier Robert 	if (sigaddset(&unset, SIGPOLL))
408c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
409c0b746e5SOllivier Robert #  endif
410c0b746e5SOllivier Robert 
411c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
412c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
413c0b746e5SOllivier Robert }
414c0b746e5SOllivier Robert 
415c0b746e5SOllivier Robert void
416c0b746e5SOllivier Robert wait_for_signal(void)
417c0b746e5SOllivier Robert {
418c0b746e5SOllivier Robert 	sigset_t old;
419c0b746e5SOllivier Robert 
420c0b746e5SOllivier Robert 	if (sigprocmask(SIG_UNBLOCK, NULL, &old))
421c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
422c0b746e5SOllivier Robert 
423c0b746e5SOllivier Robert #  if defined(USE_SIGIO)
424c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGIO))
425c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
426c0b746e5SOllivier Robert #  endif
427c0b746e5SOllivier Robert #  if defined(USE_SIGPOLL)
428c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGPOLL))
429c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
430c0b746e5SOllivier Robert #  endif
431c0b746e5SOllivier Robert 	if (sigdelset(&old, SIGALRM))
432c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
433c0b746e5SOllivier Robert 
434c0b746e5SOllivier Robert 	if (sigsuspend(&old) && (errno != EINTR))
435c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
436c0b746e5SOllivier Robert }
437c0b746e5SOllivier Robert 
438c0b746e5SOllivier Robert # else /* !HAVE_SIGACTION */
439c0b746e5SOllivier Robert /*
440c0b746e5SOllivier Robert  * Must be an old bsd system.
441c0b746e5SOllivier Robert  * We assume there is no SIGPOLL.
442c0b746e5SOllivier Robert  */
443c0b746e5SOllivier Robert 
444c0b746e5SOllivier Robert void
445c0b746e5SOllivier Robert block_io_and_alarm(void)
446c0b746e5SOllivier Robert {
447c0b746e5SOllivier Robert 	int mask;
448c0b746e5SOllivier Robert 
449c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
450c0b746e5SOllivier Robert 	if (sigblock(mask))
451c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
452c0b746e5SOllivier Robert }
453c0b746e5SOllivier Robert 
454c0b746e5SOllivier Robert void
455c0b746e5SOllivier Robert block_sigio(void)
456c0b746e5SOllivier Robert {
457c0b746e5SOllivier Robert 	int mask;
458c0b746e5SOllivier Robert 
459c0b746e5SOllivier Robert 	++sigio_block_count;
460c0b746e5SOllivier Robert 	if (sigio_block_count > 1)
461c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
462c0b746e5SOllivier Robert 	if (sigio_block_count < 1)
463c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
464c0b746e5SOllivier Robert 
465c0b746e5SOllivier Robert 	mask = sigmask(SIGIO);
466c0b746e5SOllivier Robert 	if (sigblock(mask))
467c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
468c0b746e5SOllivier Robert }
469c0b746e5SOllivier Robert 
470c0b746e5SOllivier Robert void
471c0b746e5SOllivier Robert set_signal(void)
472c0b746e5SOllivier Robert {
473c0b746e5SOllivier Robert 	(void) signal_no_reset(SIGIO, sigio_handler);
474c0b746e5SOllivier Robert }
475c0b746e5SOllivier Robert 
476c0b746e5SOllivier Robert void
477c0b746e5SOllivier Robert unblock_io_and_alarm(void)
478c0b746e5SOllivier Robert {
479c0b746e5SOllivier Robert 	int mask, omask;
480c0b746e5SOllivier Robert 
481c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
482c0b746e5SOllivier Robert 	omask = sigblock(0);
483c0b746e5SOllivier Robert 	omask &= ~mask;
484c0b746e5SOllivier Robert 	(void) sigsetmask(omask);
485c0b746e5SOllivier Robert }
486c0b746e5SOllivier Robert 
487c0b746e5SOllivier Robert void
488c0b746e5SOllivier Robert unblock_sigio(void)
489c0b746e5SOllivier Robert {
490c0b746e5SOllivier Robert 	int mask, omask;
491c0b746e5SOllivier Robert 
492c0b746e5SOllivier Robert 	--sigio_block_count;
493c0b746e5SOllivier Robert 	if (sigio_block_count > 0)
494c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
495c0b746e5SOllivier Robert 	if (sigio_block_count < 0)
496c0b746e5SOllivier Robert 	    msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
497c0b746e5SOllivier Robert 	mask = sigmask(SIGIO);
498c0b746e5SOllivier Robert 	omask = sigblock(0);
499c0b746e5SOllivier Robert 	omask &= ~mask;
500c0b746e5SOllivier Robert 	(void) sigsetmask(omask);
501c0b746e5SOllivier Robert }
502c0b746e5SOllivier Robert 
503c0b746e5SOllivier Robert void
504c0b746e5SOllivier Robert wait_for_signal(void)
505c0b746e5SOllivier Robert {
506c0b746e5SOllivier Robert 	int mask, omask;
507c0b746e5SOllivier Robert 
508c0b746e5SOllivier Robert 	mask = sigmask(SIGIO) | sigmask(SIGALRM);
509c0b746e5SOllivier Robert 	omask = sigblock(0);
510c0b746e5SOllivier Robert 	omask &= ~mask;
511c0b746e5SOllivier Robert 	if (sigpause(omask) && (errno != EINTR))
512c0b746e5SOllivier Robert 	    msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
513c0b746e5SOllivier Robert }
514c0b746e5SOllivier Robert 
515c0b746e5SOllivier Robert # endif /* HAVE_SIGACTION */
516c0b746e5SOllivier Robert #else
517c0b746e5SOllivier Robert int  NotAnEmptyCompilationUnit;
518c0b746e5SOllivier Robert #endif
519