aboutsummaryrefslogtreecommitdiff
path: root/src/runscript.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2007-04-20 18:58:42 +0000
committerRoy Marples <roy@marples.name>2007-04-20 18:58:42 +0000
commit35ee67f446277f5777a5b9f7feff3e37b315d9d0 (patch)
tree18582ab2a6ccc89bcefbfc9771c777b5ad68c7ba /src/runscript.c
parenta5ba34ec151e4e18d7b732dac1517d21a1df3710 (diff)
Re-work the starting and stopping of services so we always know the pid so we can kill our children without the need for process groups which we cannot use as keyboard will not work in init.
Diffstat (limited to 'src/runscript.c')
-rw-r--r--src/runscript.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/src/runscript.c b/src/runscript.c
index c82c5f9a..73333605 100644
--- a/src/runscript.c
+++ b/src/runscript.c
@@ -9,7 +9,6 @@
#define APPLET "runscript"
#include <sys/types.h>
-#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dlfcn.h>
@@ -17,6 +16,7 @@
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -49,6 +49,7 @@ static bool sighup = false;
static char *ibsave = NULL;
static bool in_background = false;
static rc_hook_t hook_out = 0;
+static pid_t service_pid = 0;
extern char **environ;
@@ -108,6 +109,8 @@ static void handle_signal (int sig)
return;
}
} while (! WIFEXITED (status) && ! WIFSIGNALED (status));
+ if (pid == service_pid)
+ service_pid = 0;
break;
case SIGINT:
@@ -119,6 +122,9 @@ static void handle_signal (int sig)
case SIGQUIT:
if (! signame[0])
snprintf (signame, sizeof (signame), "SIGQUIT");
+ /* Send the signal to our children too */
+ if (service_pid > 0)
+ kill (service_pid, sig);
eerrorx ("%s: caught %s, aborting", applet, signame);
default:
@@ -259,18 +265,17 @@ static void cleanup (void)
static bool svc_exec (const char *service, const char *arg1, const char *arg2)
{
- int status = 0;
- pid_t pid;
+ bool retval;
/* We need to disable our child signal handler now so we block
until our script returns. */
signal (SIGCHLD, NULL);
- pid = vfork();
+ service_pid = vfork();
- if (pid == -1)
+ if (service_pid == -1)
eerrorx ("%s: vfork: %s", service, strerror (errno));
- if (pid == 0) {
+ if (service_pid == 0) {
if (rc_exists (RC_SVCDIR "runscript.sh")) {
execl (RC_SVCDIR "runscript.sh", service, service, arg1, arg2,
(char *) NULL);
@@ -286,21 +291,13 @@ static bool svc_exec (const char *service, const char *arg1, const char *arg2)
}
}
- do {
- if (waitpid (pid, &status, 0) < 0) {
- if (errno != ECHILD)
- eerror ("waitpid: %s", strerror (errno));
- break;
- }
- } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
+ retval = rc_waitpid (service_pid) == 0 ? true : false;
+ service_pid = 0;
/* Done, so restore the signal handler */
signal (SIGCHLD, handle_signal);
- if (WIFEXITED (status))
- return (WEXITSTATUS (status) ? false : true);
-
- return (false);
+ return (retval);
}
static rc_service_state_t svc_status (const char *service)
@@ -467,8 +464,11 @@ static void svc_start (const char *service, bool deps)
services = rc_get_depends (deptree, types, svclist,
softlevel, depoptions);
STRLIST_FOREACH (services, svc, i)
- if (rc_service_state (svc, rc_service_stopped))
- rc_start_service (svc);
+ if (rc_service_state (svc, rc_service_stopped)) {
+ pid_t pid = rc_start_service (svc);
+ if (! rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
+ rc_waitpid (pid);
+ }
rc_strlist_free (services);
}
@@ -669,7 +669,9 @@ static void svc_stop (const char *service, bool deps)
if (rc_service_state (svc, rc_service_started) ||
rc_service_state (svc, rc_service_inactive))
{
- rc_stop_service (svc);
+ pid_t pid = rc_stop_service (svc);
+ if (! rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
+ rc_waitpid (pid);
tmplist = rc_strlist_add (tmplist, svc);
}
}