From: Roy Marples Date: Sat, 2 Feb 2008 21:56:12 +0000 (+0000) Subject: Revert posix_spawn as it seems only glibc supports it for us right now. Hope that... X-Git-Tag: v3.2.3~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b3ab874f4aec73ed01dfb8055a05cd813d27342;p=thirdparty%2Fdhcpcd.git Revert posix_spawn as it seems only glibc supports it for us right now. Hope that libc is tolerant to changing signals inside a vfork if we put them back afterwards in the parent. --- diff --git a/client.c b/client.c index e6bb12de..163e9cd6 100644 --- a/client.c +++ b/client.c @@ -1059,6 +1059,8 @@ int dhcp_run (const options_t *options, int *pidfd) if (! client_setup (state, options)) goto eexit; + if (signal_init () == -1) + goto eexit; if (signal_setup () == -1) goto eexit; diff --git a/configure.c b/configure.c index 6372ee55..559ba338 100644 --- a/configure.c +++ b/configure.c @@ -41,21 +41,11 @@ #include #include #include +#include #include #include #include -#ifndef BSD -# define HAVE_POSIX_SPAWN -#endif - -#ifdef HAVE_POSIX_SPAWN -# include -extern char **environ; -#else -# include -#endif - #include "config.h" #include "common.h" #include "configure.h" @@ -66,11 +56,8 @@ extern char **environ; #include "interface.h" #include "dhcpcd.h" #include "logger.h" -#include "socket.h" - -#ifndef HAVE_POSIX_SPAWN #include "signal.h" -#endif +#include "socket.h" static int file_in_path (const char *file) { @@ -106,11 +93,9 @@ static int exec_cmd (const char *cmd, const char *args, ...) char **argv; int n = 1; int ret; -#ifndef HAVE_POSIX_SPAWN pid_t pid; sigset_t full; sigset_t old; -#endif va_start (va, args); while (va_arg (va, char *) != NULL) @@ -126,38 +111,40 @@ static int exec_cmd (const char *cmd, const char *args, ...) n++; va_end (va); -#ifdef HAVE_POSIX_SPAWN - errno = 0; - ret = posix_spawnp (NULL, argv[0], NULL, NULL, argv, environ); - if (ret != 0 || errno != 0) { - logger (LOG_ERR, "error executing \"%s\": %s", - cmd, strerror (errno)); - ret = -1; - } -#else /* OK, we need to block signals */ sigfillset (&full); sigprocmask (SIG_SETMASK, &full, &old); - switch (pid = fork()) { +#ifdef THERE_IS_NO_FORK + signal_reset (); + pid = vfork (); +#else + pid = fork(); +#endif + + switch (pid) { case -1: logger (LOG_ERR, "vfork: %s", strerror (errno)); ret = -1; break; case 0: - /* Reset signals and clear block */ +#ifndef THERE_IS_NO_FORK signal_reset (); +#endif sigprocmask (SIG_SETMASK, &old, NULL); if (execvp (cmd, argv) && errno != ENOENT) logger (LOG_ERR, "error executing \"%s\": %s", cmd, strerror (errno)); - _exit (0); + _exit (111); /* NOTREACHED */ } +#ifdef THERE_IS_NO_FORK + signal_setup (); +#endif + /* Restore our signals */ sigprocmask (SIG_SETMASK, &old, NULL); -#endif free (argv); return (ret); diff --git a/signal.c b/signal.c index d38efb47..b68375c7 100644 --- a/signal.c +++ b/signal.c @@ -125,7 +125,7 @@ int signal_read (fd_set *rset) /* Call this before doing anything else. Sets up the socket pair * and installs the signal handler */ -int signal_setup (void) +int signal_init (void) { unsigned int i; int flags; @@ -142,16 +142,8 @@ int signal_setup (void) fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1) logger (LOG_ERR ,"fcntl: %s", strerror (errno)); - memset (&sa, 0, sizeof (sa)); - sa.sa_handler = signal_handler; - sigemptyset (&sa.sa_mask); - for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++) - if (sigaction (handle_sigs[i], &sa, NULL) == -1) { - logger (LOG_ERR, "sigaction: %s", strerror (errno)); - return (-1); - } - - /* Ignore child signals and don't make zombies */ + /* Ignore child signals and don't make zombies. + * Because we do this, we don't need to be in signal_setup */ sa.sa_handler = SIG_DFL; sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT; if (sigaction (SIGCHLD, &sa, NULL) == -1) { @@ -160,7 +152,24 @@ int signal_setup (void) } memset (signals, 0, sizeof (signals)); + return (0); +} + +int signal_setup (void) +{ + unsigned int i; + struct sigaction sa; + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = signal_handler; + sigemptyset (&sa.sa_mask); + + for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++) + if (sigaction (handle_sigs[i], &sa, NULL) == -1) { + logger (LOG_ERR, "sigaction: %s", strerror (errno)); + return (-1); + } + return (0); } diff --git a/signal.h b/signal.h index d7baa6e0..e72b9964 100644 --- a/signal.h +++ b/signal.h @@ -28,6 +28,7 @@ #ifndef SIGNAL_H #define SIGNAL_H +int signal_init (void); int signal_setup (void); int signal_reset (void); int signal_fd_set (fd_set *rset, int fd);