#include <unistd.h>
#ifndef BSD
-#define HAVE_POSIX_SPAWN
+# define HAVE_POSIX_SPAWN
#endif
#ifdef HAVE_POSIX_SPAWN
-#include <spawn.h>
+# include <spawn.h>
+extern char **environ;
+#else
+# include <signal.h>
#endif
#include "config.h"
#include "logger.h"
#include "socket.h"
-extern char **environ;
+#ifndef HAVE_POSIX_SPAWN
+#include "signal.h"
+#endif
static int file_in_path (const char *file)
{
int ret;
#ifndef HAVE_POSIX_SPAWN
pid_t pid;
+ sigset_t full;
+ sigset_t old;
#endif
va_start (va, args);
ret = -1;
}
#else
- if ((pid = vfork ()) == 0) {
- if (execvp (cmd, argv) && errno != ENOENT)
- logger (LOG_ERR, "error executing \"%s\": %s",
- cmd, strerror (errno));
- _exit (0);
- } else if (pid == -1) {
- logger (LOG_ERR, "vfork: %s", strerror (errno));
- ret = -1;
+ /* OK, we need to block signals */
+ sigfillset (&full);
+ sigprocmask (SIG_SETMASK, &full, &old);
+
+ switch (pid = fork()) {
+ case -1:
+ logger (LOG_ERR, "vfork: %s", strerror (errno));
+ ret = -1;
+ break;
+ case 0:
+ /* Reset signals and clear block */
+ signal_reset ();
+ sigprocmask (SIG_SETMASK, &old, NULL);
+ if (execvp (cmd, argv) && errno != ENOENT)
+ logger (LOG_ERR, "error executing \"%s\": %s",
+ cmd, strerror (errno));
+ _exit (0);
+ /* NOTREACHED */
}
+
+ /* Restore our signals */
+ sigprocmask (SIG_SETMASK, &old, NULL);
#endif
free (argv);
return (0);
}
+
+int signal_reset (void)
+{
+ struct sigaction sa;
+ unsigned int i;
+
+ memset (&sa, 0, sizeof (sa));
+ sa.sa_handler = SIG_DFL;
+ 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);
+}