if (! client_setup (state, options))
goto eexit;
+ if (signal_init () == -1)
+ goto eexit;
if (signal_setup () == -1)
goto eexit;
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
-#ifndef BSD
-# define HAVE_POSIX_SPAWN
-#endif
-
-#ifdef HAVE_POSIX_SPAWN
-# include <spawn.h>
-extern char **environ;
-#else
-# include <signal.h>
-#endif
-
#include "config.h"
#include "common.h"
#include "configure.h"
#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)
{
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)
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);
/* 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;
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) {
}
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);
}
#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);