summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/libntp/iosignal.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
committerroberto <roberto@FreeBSD.org>1999-12-09 13:01:21 +0000
commitef64b99e8412f2273dd2e8b3291c2f78ffc4667f (patch)
treefc0cfa1aab0ff6b228f511b410733ef4f35d1ead /contrib/ntp/libntp/iosignal.c
downloadFreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.zip
FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.tar.gz
Virgin import of ntpd 4.0.98f
Diffstat (limited to 'contrib/ntp/libntp/iosignal.c')
-rw-r--r--contrib/ntp/libntp/iosignal.c518
1 files changed, 518 insertions, 0 deletions
diff --git a/contrib/ntp/libntp/iosignal.c b/contrib/ntp/libntp/iosignal.c
new file mode 100644
index 0000000..c8ec949
--- /dev/null
+++ b/contrib/ntp/libntp/iosignal.c
@@ -0,0 +1,518 @@
+/*
+ * ntp_io.c - input/output routines for ntpd. The socket-opening code
+ * was shamelessly stolen from ntpd.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
+# include <sys/sockio.h>
+#endif
+#include <arpa/inet.h>
+
+#if _BSDI_VERSION >= 199510
+# include <ifaddrs.h>
+#endif
+/* 98/06/01 */
+#include "ntp_machine.h" /* 98/06/01 */
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_if.h"
+#include "ntp_stdlib.h"
+#include "iosignal.h"
+
+#if defined(HAVE_SIGNALED_IO)
+static int sigio_block_count = 0;
+extern void input_handler P((l_fp *));
+
+/*
+ * SIGPOLL and SIGIO ROUTINES.
+ */
+
+ /*
+ * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
+ * a few have separate SIGIO and SIGPOLL signals. This code checks for the
+ * SIGIO == SIGPOLL case at compile time.
+ * Do not defined USE_SIGPOLL or USE_SIGIO.
+ * these are interal only to ntp_io.c!
+ */
+# if defined(USE_SIGPOLL)
+# undef USE_SIGPOLL
+# endif
+# if defined(USE_SIGIO)
+# undef USE_SIGIO
+# endif
+
+# if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
+# define USE_SIGPOLL
+# endif
+
+# if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
+# define USE_SIGIO
+# endif
+
+# if defined(USE_SIGIO) && defined(USE_SIGPOLL)
+# if SIGIO == SIGPOLL
+# define USE_SIGIO
+# undef USE_SIGPOLL
+# endif /* SIGIO == SIGPOLL */
+# endif /* USE_SIGIO && USE_SIGIO */
+
+
+/*
+ * TTY initialization routines.
+ */
+int
+init_clock_sig(
+ struct refclockio *rio
+ )
+{
+# ifdef USE_TTY_SIGPOLL
+ {
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
+ {
+ msyslog(LOG_ERR,
+ "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
+ return 1;
+ }
+ return 0;
+ }
+# else
+ /*
+ * Special cases first!
+ */
+ /* Was: defined(SYS_HPUX) */
+# if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
+#define CLOCK_DONE
+ {
+ int pgrp, on = 1;
+
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ pgrp = getpid();
+ if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * set non-blocking, async I/O on the descriptor
+ */
+ if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ return 0;
+ }
+# endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
+ /* Was: defined(SYS_AIX) && !defined(_BSD) */
+# if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
+ /*
+ * SYSV compatibility mode under AIX.
+ */
+#define CLOCK_DONE
+ {
+ int pgrp, on = 1;
+
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ pgrp = -getpid();
+ if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
+ return 1;
+ }
+
+ if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ return 0;
+ }
+# endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
+# ifndef CLOCK_DONE
+ {
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+# if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
+ /*
+ * there are, however, always exceptions to the rules
+ * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
+ * CTTYs. SunOS and HPUX do not semm to have this restriction.
+ * another question is: how can you do multiple SIGIO from several
+ * ttys (as they all should be CTTYs), wondering...
+ *
+ * kd 95-07-16
+ */
+ if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
+ return 1;
+ }
+# endif /* TIOCSCTTY && USE_FSETOWNCTTY */
+
+ if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
+ return 1;
+ }
+
+ if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR,
+ "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ return 0;
+ }
+# endif /* CLOCK_DONE */
+# endif /* !USE_TTY_SIGPOLL */
+}
+
+
+
+void
+init_socket_sig(
+ int fd
+ )
+{
+# ifdef USE_UDP_SIGPOLL
+ {
+ if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
+ {
+ msyslog(LOG_ERR,
+ "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
+ exit(1);
+ }
+ }
+# else /* USE_UDP_SIGPOLL */
+ {
+ int pgrp;
+# ifdef FIOASYNC
+ int on = 1;
+# endif
+
+# if defined(FIOASYNC)
+ if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(FASYNC)
+ {
+ int flags;
+
+ if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ }
+# else
+# include "Bletch: Need asynchronous I/O!"
+# endif
+
+# ifdef UDP_BACKWARDS_SETOWN
+ pgrp = -getpid();
+# else
+ pgrp = getpid();
+# endif
+
+# if defined(SIOCSPGRP)
+ if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(FIOSETOWN)
+ if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(F_SETOWN)
+ if (fcntl(fd, F_SETOWN, pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# else
+# include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
+# endif
+ }
+# endif /* USE_UDP_SIGPOLL */
+}
+
+RETSIGTYPE
+sigio_handler(
+ int sig
+ )
+{
+ int saved_errno = errno;
+ l_fp ts;
+
+ get_systime(&ts);
+ (void)input_handler(&ts);
+ errno = saved_errno;
+}
+
+/*
+ * Signal support routines.
+ */
+# ifdef HAVE_SIGACTION
+void
+set_signal(void)
+{
+# ifdef USE_SIGIO
+ (void) signal_no_reset(SIGIO, sigio_handler);
+# endif
+# ifdef USE_SIGPOLL
+ (void) signal_no_reset(SIGPOLL, sigio_handler);
+# endif
+}
+
+void
+block_io_and_alarm(void)
+{
+ sigset_t set;
+
+ if (sigemptyset(&set))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
+# if defined(USE_SIGIO)
+ if (sigaddset(&set, SIGIO))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&set, SIGPOLL))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
+# endif
+ if (sigaddset(&set, SIGALRM))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
+
+ if (sigprocmask(SIG_BLOCK, &set, NULL))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
+}
+
+void
+block_sigio(void)
+{
+ sigset_t set;
+
+ ++sigio_block_count;
+ if (sigio_block_count > 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
+ if (sigio_block_count < 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
+
+ if (sigemptyset(&set))
+ msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
+# if defined(USE_SIGIO)
+ if (sigaddset(&set, SIGIO))
+ msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&set, SIGPOLL))
+ msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
+# endif
+
+ if (sigprocmask(SIG_BLOCK, &set, NULL))
+ msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
+}
+
+void
+unblock_io_and_alarm(void)
+{
+ sigset_t unset;
+
+ if (sigemptyset(&unset))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigaddset(&unset, SIGIO))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&unset, SIGPOLL))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
+# endif
+ if (sigaddset(&unset, SIGALRM))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
+
+ if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
+}
+
+void
+unblock_sigio(void)
+{
+ sigset_t unset;
+
+ --sigio_block_count;
+ if (sigio_block_count > 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
+ if (sigio_block_count < 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
+
+ if (sigemptyset(&unset))
+ msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigaddset(&unset, SIGIO))
+ msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&unset, SIGPOLL))
+ msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
+# endif
+
+ if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
+ msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
+}
+
+void
+wait_for_signal(void)
+{
+ sigset_t old;
+
+ if (sigprocmask(SIG_UNBLOCK, NULL, &old))
+ msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigdelset(&old, SIGIO))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigdelset(&old, SIGPOLL))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
+# endif
+ if (sigdelset(&old, SIGALRM))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
+
+ if (sigsuspend(&old) && (errno != EINTR))
+ msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
+}
+
+# else /* !HAVE_SIGACTION */
+/*
+ * Must be an old bsd system.
+ * We assume there is no SIGPOLL.
+ */
+
+void
+block_io_and_alarm(void)
+{
+ int mask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ if (sigblock(mask))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
+}
+
+void
+block_sigio(void)
+{
+ int mask;
+
+ ++sigio_block_count;
+ if (sigio_block_count > 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
+ if (sigio_block_count < 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
+
+ mask = sigmask(SIGIO);
+ if (sigblock(mask))
+ msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
+}
+
+void
+set_signal(void)
+{
+ (void) signal_no_reset(SIGIO, sigio_handler);
+}
+
+void
+unblock_io_and_alarm(void)
+{
+ int mask, omask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ omask = sigblock(0);
+ omask &= ~mask;
+ (void) sigsetmask(omask);
+}
+
+void
+unblock_sigio(void)
+{
+ int mask, omask;
+
+ --sigio_block_count;
+ if (sigio_block_count > 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
+ if (sigio_block_count < 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
+ mask = sigmask(SIGIO);
+ omask = sigblock(0);
+ omask &= ~mask;
+ (void) sigsetmask(omask);
+}
+
+void
+wait_for_signal(void)
+{
+ int mask, omask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ omask = sigblock(0);
+ omask &= ~mask;
+ if (sigpause(omask) && (errno != EINTR))
+ msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
+}
+
+# endif /* HAVE_SIGACTION */
+#else
+int NotAnEmptyCompilationUnit;
+#endif
OpenPOWER on IntegriCloud