193 lines
5.1 KiB
Diff
193 lines
5.1 KiB
Diff
diff -Naur inetutils-1.9.2-orig/libinetutils/daemon.c inetutils-1.9.2/libinetutils/daemon.c
|
|
--- inetutils-1.9.2-orig/libinetutils/daemon.c 2013-12-03 17:57:44.000000000 +0300
|
|
+++ inetutils-1.9.2/libinetutils/daemon.c 2014-12-12 11:55:11.043600000 +0300
|
|
@@ -51,6 +51,7 @@
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
+#include <syslog.h>
|
|
#include <error.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
@@ -103,13 +104,87 @@
|
|
|
|
#define MAXFD 64
|
|
|
|
-void
|
|
+/* copy signal stuff from inetd.c -- POSIX says that the various
|
|
+ signal interfaces should not be mixed in the same program.
|
|
+ Because inetd uses 'most recent signal interface' it can find,
|
|
+ we should too.
|
|
+*/
|
|
+
|
|
+#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
|
|
+#if defined(HAVE_SIGACTION)
|
|
+# define SIGSTATUS sigset_t
|
|
+# define sigstatus_empty(s) sigemptyset(&s)
|
|
+#else
|
|
+# define SIGSTATUS long
|
|
+# define sigstatus_empty(s) s = 0
|
|
+#endif
|
|
+
|
|
+static void
|
|
+signal_set_handler (int signo, RETSIGTYPE (*handler) ())
|
|
+{
|
|
+#if defined(HAVE_SIGACTION)
|
|
+ struct sigaction sa;
|
|
+ memset ((char *)&sa, 0, sizeof(sa));
|
|
+ sigemptyset (&sa.sa_mask);
|
|
+ sigaddset (&sa.sa_mask, signo);
|
|
+#ifdef SA_RESTART
|
|
+ sa.sa_flags = SA_RESTART;
|
|
+#endif
|
|
+ sa.sa_handler = handler;
|
|
+ sigaction (signo, &sa, NULL);
|
|
+#elif defined(HAVE_SIGVEC)
|
|
+ struct sigvec sv;
|
|
+ memset (&sv, 0, sizeof(sv));
|
|
+ sv.sv_mask = SIGBLOCK;
|
|
+ sv.sv_handler = handler;
|
|
+ sigvec (signo, &sv, NULL);
|
|
+#else /* !HAVE_SIGVEC */
|
|
+ signal (signo, handler);
|
|
+#endif /* HAVE_SIGACTION */
|
|
+}
|
|
+
|
|
+static void
|
|
+signal_block (SIGSTATUS *old_status)
|
|
+{
|
|
+#ifdef HAVE_SIGACTION
|
|
+ sigset_t sigs;
|
|
+
|
|
+ sigemptyset (&sigs);
|
|
+ sigaddset (&sigs, SIGCHLD);
|
|
+ sigaddset (&sigs, SIGHUP);
|
|
+ sigaddset (&sigs, SIGALRM);
|
|
+ sigprocmask (SIG_BLOCK, &sigs, old_status);
|
|
+#else
|
|
+ long omask = sigblock (SIGBLOCK);
|
|
+ if (old_status)
|
|
+ *old_status = omask;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static void
|
|
+signal_unblock (SIGSTATUS *status)
|
|
+{
|
|
+#ifdef HAVE_SIGACTION
|
|
+ if (status)
|
|
+ sigprocmask (SIG_SETMASK, status, 0);
|
|
+ else
|
|
+ {
|
|
+ sigset_t empty;
|
|
+ sigemptyset (&empty);
|
|
+ sigprocmask (SIG_SETMASK, &empty, 0);
|
|
+ }
|
|
+#else
|
|
+ sigsetmask (status ? *status : 0);
|
|
+#endif
|
|
+}
|
|
+
|
|
+RETSIGTYPE
|
|
waitdaemon_timeout (int signo _GL_UNUSED_PARAMETER)
|
|
{
|
|
int left;
|
|
|
|
left = alarm (0);
|
|
- signal (SIGALRM, SIG_DFL);
|
|
+ signal_set_handler (SIGALRM, SIG_DFL);
|
|
if (left == 0)
|
|
error (EXIT_FAILURE, 0, "timed out waiting for child");
|
|
}
|
|
@@ -138,9 +213,29 @@
|
|
default: /* In the parent. */
|
|
if (maxwait > 0)
|
|
{
|
|
- signal (SIGALRM, waitdaemon_timeout);
|
|
+ int status;
|
|
+ pid_t wpid;
|
|
+
|
|
+ signal_unblock(NULL);
|
|
+ signal_set_handler (SIGALRM, waitdaemon_timeout);
|
|
alarm (maxwait);
|
|
- pause ();
|
|
+ do
|
|
+ {
|
|
+ wpid = waitpid(childpid, &status, WUNTRACED
|
|
+#ifdef WCONTINUED /* Not all implementations support this */
|
|
+ | WCONTINUED
|
|
+#endif
|
|
+ );
|
|
+ if (wpid == -1)
|
|
+ {
|
|
+ /* should't happen for timeouts, because the
|
|
+ SIGALRM handler will error (and exit). However,
|
|
+ we may recieve some OTHER signal...
|
|
+ */
|
|
+ error (1, 0, "interrupted while waiting for child");
|
|
+ }
|
|
+ }
|
|
+ while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
|
}
|
|
_exit (EXIT_SUCCESS);
|
|
}
|
|
@@ -152,7 +247,7 @@
|
|
then SIGHUP is sent to all process belonging to the same session,
|
|
i.e., also to the second child.
|
|
*/
|
|
- signal (SIGHUP, SIG_IGN);
|
|
+ signal_set_handler (SIGHUP, SIG_IGN);
|
|
|
|
switch (fork ())
|
|
{
|
|
@@ -202,5 +297,9 @@
|
|
int
|
|
daemon (int nochdir, int noclose)
|
|
{
|
|
+#ifdef __CYGWIN__
|
|
+ return (waitdaemon (nochdir, noclose, 5) == -1) ? -1 : 0;
|
|
+#else
|
|
return (waitdaemon (nochdir, noclose, 0) == -1) ? -1 : 0;
|
|
+#endif
|
|
}
|
|
diff -Naur inetutils-1.9.2-orig/libinetutils/logwtmp.c inetutils-1.9.2/libinetutils/logwtmp.c
|
|
--- inetutils-1.9.2-orig/libinetutils/logwtmp.c 2013-09-26 12:36:38.000000000 +0300
|
|
+++ inetutils-1.9.2/libinetutils/logwtmp.c 2014-12-12 11:55:11.043600000 +0300
|
|
@@ -50,6 +50,10 @@
|
|
extern int errno;
|
|
#endif
|
|
|
|
+#ifndef O_BINARY
|
|
+#define O_BINARY 0
|
|
+#endif
|
|
+
|
|
#ifdef HAVE_UTMPX_H
|
|
static void
|
|
_logwtmp (struct utmpx *ut)
|
|
@@ -62,9 +66,9 @@
|
|
static int fd = -1;
|
|
|
|
if (fd < 0)
|
|
- fd = open (OUR_WTMP, O_WRONLY | O_APPEND, 0);
|
|
+ fd = open (OUR_WTMP, O_WRONLY | O_APPEND | O_BINARY, 0);
|
|
#else
|
|
- int fd = open (OUR_WTMP, O_WRONLY | O_APPEND, 0);
|
|
+ int fd = open (OUR_WTMP, O_WRONLY | O_APPEND | O_BINARY, 0);
|
|
#endif
|
|
|
|
if (fd >= 0)
|
|
diff -Naur inetutils-1.9.2-orig/libinetutils/setsig.c inetutils-1.9.2/libinetutils/setsig.c
|
|
--- inetutils-1.9.2-orig/libinetutils/setsig.c 2013-09-26 12:36:38.000000000 +0300
|
|
+++ inetutils-1.9.2/libinetutils/setsig.c 2014-12-12 11:55:11.059200000 +0300
|
|
@@ -26,6 +26,10 @@
|
|
|
|
#include <signal.h>
|
|
|
|
+#ifdef __CYGWIN__
|
|
+typedef _sig_func_ptr sig_t;
|
|
+#endif
|
|
+
|
|
/* This is exactly like the traditional signal function, but turns on the
|
|
SA_RESTART bit where possible. */
|
|
sighandler_t
|