int err = -1;
char **aargv;
sigset_t mask, omask;
- int i;
+ int i, shutdown = 0;
while (1) {
int ret = getopt_long_only(argc, argv, "", options, NULL);
aargv = &argv[optind];
argc -= nbargs;
+ /*
+ * mask all the signals so we are safe to install a
+ * signal handler and to fork
+ */
sigfillset(&mask);
sigprocmask(SIG_SETMASK, &mask, &omask);
struct sigaction act;
sigfillset(&act.sa_mask);
+ sigdelset(&mask, SIGILL);
+ sigdelset(&mask, SIGSEGV);
+ sigdelset(&mask, SIGBUS);
act.sa_flags = 0;
act.sa_handler = interrupt_handler;
sigaction(i, &act, NULL);
if (!pid) {
+ /* restore default signal handlers */
for (i = 1; i < NSIG; i++)
signal(i, SIG_DFL);
+
sigprocmask(SIG_SETMASK, &omask, NULL);
NOTICE("about to exec '%s'", aargv[0]);
exit(err);
}
+ /* let's process the signals now */
+ sigdelset(&omask, SIGALRM);
sigprocmask(SIG_SETMASK, &omask, NULL);
/* no need of other inherited fds but stderr */
break;
case SIGTERM:
- kill(-1, SIGTERM);
+ if (!shutdown) {
+ shutdown = 1;
+ kill(-1, SIGTERM);
+ alarm(1);
+ }
+ break;
+
+ case SIGALRM:
+ kill(-1, SIGKILL);
break;
default:
goto out;
if (errno == EINTR)
continue;
- ERROR("failed to wait child : %s", strerror(errno));
+
+ ERROR("failed to wait child : %s",
+ strerror(errno));
goto out;
}
+ /* reset timer each time a process exited */
+ if (shutdown)
+ alarm(1);
+
/*
- * keep the exit code of started application (not wrapped pid)
- * and continue to wait for the end of the orphan group.
+ * keep the exit code of started application
+ * (not wrapped pid) and continue to wait for
+ * the end of the orphan group.
*/
if ((waited_pid != pid) || (orphan ==1))
continue;