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