summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/compat/pselect.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/nsd/compat/pselect.c')
-rw-r--r--usr.sbin/nsd/compat/pselect.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/usr.sbin/nsd/compat/pselect.c b/usr.sbin/nsd/compat/pselect.c
new file mode 100644
index 00000000000..524cf2837a0
--- /dev/null
+++ b/usr.sbin/nsd/compat/pselect.c
@@ -0,0 +1,44 @@
+/*
+ * Like select(2) but set the signals to block while waiting in
+ * select. This version is not entirely race condition safe. Only
+ * operating system support can make it so.
+ */
+
+#include <config.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <unistd.h>
+#include <signal.h>
+
+int
+pselect (int n,
+ fd_set *readfds,
+ fd_set *writefds,
+ fd_set *exceptfds,
+ const struct timespec *timeout,
+ const sigset_t *sigmask)
+{
+ int result;
+ sigset_t saved_sigmask;
+ struct timeval saved_timeout;
+
+ if (sigmask && sigprocmask(SIG_SETMASK, sigmask, &saved_sigmask) == -1)
+ return -1;
+
+ if (timeout) {
+ saved_timeout.tv_sec = timeout->tv_sec;
+ saved_timeout.tv_usec = timeout->tv_nsec / 1000;
+ result = select(n, readfds, writefds, exceptfds, &saved_timeout);
+ } else {
+ result = select(n, readfds, writefds, exceptfds, NULL);
+ }
+
+ if (sigmask && sigprocmask(SIG_SETMASK, &saved_sigmask, NULL) == -1)
+ return -1;
+
+ return result;
+}