Miroslav Lichvar
2015-05-14 12:23:04 UTC
Instead of killing the whole process group, which may contain other
processes than timemaster and its children (e.g. when it is started from
a shell script), save the PIDs and kill the processes individually.
Signed-off-by: Miroslav Lichvar <***@redhat.com>
---
timemaster.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/timemaster.c b/timemaster.c
index eec0d0d..76e48b3 100644
--- a/timemaster.c
+++ b/timemaster.c
@@ -897,7 +897,7 @@ static struct script *script_create(struct timemaster_config *config)
return script;
}
-static int start_program(char **command, sigset_t *mask)
+static pid_t start_program(char **command, sigset_t *mask)
{
char **arg, *s;
pid_t pid;
@@ -907,7 +907,7 @@ static int start_program(char **command, sigset_t *mask)
if (posix_spawnattr_init(&attr)) {
pr_err("failed to init spawn attributes: %m");
- return 1;
+ return 0;
}
if (posix_spawnattr_setsigmask(&attr, mask) ||
@@ -915,7 +915,7 @@ static int start_program(char **command, sigset_t *mask)
posix_spawnp(&pid, command[0], NULL, &attr, command, environ)) {
pr_err("failed to spawn %s: %m", command[0]);
posix_spawnattr_destroy(&attr);
- return 1;
+ return 0;
}
posix_spawnattr_destroy(&attr);
@@ -924,7 +924,7 @@ static int start_program(char **command, sigset_t *mask)
if (pid < 0) {
pr_err("fork() failed: %m");
- return 1;
+ return 0;
}
if (!pid) {
@@ -949,7 +949,7 @@ static int start_program(char **command, sigset_t *mask)
free(s);
- return 0;
+ return pid;
}
static int create_config_files(struct config_file **configs)
@@ -1009,9 +1009,8 @@ static int script_run(struct script *script)
{
sigset_t mask, old_mask;
siginfo_t info;
- pid_t pid;
- int status, ret = 0;
- char ***command;
+ pid_t pid, *pids;
+ int i, num_commands, status, ret = 0;
if (create_config_files(script->configs))
return 1;
@@ -1028,8 +1027,14 @@ static int script_run(struct script *script)
return 1;
}
- for (command = script->commands; *command; command++) {
- if (start_program(*command, &old_mask)) {
+ for (num_commands = 0; script->commands[num_commands]; num_commands++)
+ ;
+
+ pids = calloc(num_commands, sizeof(*pids));
+
+ for (i = 0; i < num_commands; i++) {
+ pids[i] = start_program(script->commands[i], &old_mask);
+ if (!pids[i]) {
kill(getpid(), SIGTERM);
break;
}
@@ -1047,8 +1052,13 @@ static int script_run(struct script *script)
pr_info("received signal %d", info.si_signo);
- /* kill the process group */
- kill(0, SIGTERM);
+ /* kill all started processes */
+ for (i = 0; i < num_commands; i++) {
+ if (pids[i] > 0) {
+ pr_debug("killing process %d", pids[i]);
+ kill(pids[i], SIGTERM);
+ }
+ }
while ((pid = wait(&status)) >= 0) {
if (!WIFEXITED(status)) {
@@ -1062,6 +1072,8 @@ static int script_run(struct script *script)
}
}
+ free(pids);
+
if (remove_config_files(script->configs))
return 1;
processes than timemaster and its children (e.g. when it is started from
a shell script), save the PIDs and kill the processes individually.
Signed-off-by: Miroslav Lichvar <***@redhat.com>
---
timemaster.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/timemaster.c b/timemaster.c
index eec0d0d..76e48b3 100644
--- a/timemaster.c
+++ b/timemaster.c
@@ -897,7 +897,7 @@ static struct script *script_create(struct timemaster_config *config)
return script;
}
-static int start_program(char **command, sigset_t *mask)
+static pid_t start_program(char **command, sigset_t *mask)
{
char **arg, *s;
pid_t pid;
@@ -907,7 +907,7 @@ static int start_program(char **command, sigset_t *mask)
if (posix_spawnattr_init(&attr)) {
pr_err("failed to init spawn attributes: %m");
- return 1;
+ return 0;
}
if (posix_spawnattr_setsigmask(&attr, mask) ||
@@ -915,7 +915,7 @@ static int start_program(char **command, sigset_t *mask)
posix_spawnp(&pid, command[0], NULL, &attr, command, environ)) {
pr_err("failed to spawn %s: %m", command[0]);
posix_spawnattr_destroy(&attr);
- return 1;
+ return 0;
}
posix_spawnattr_destroy(&attr);
@@ -924,7 +924,7 @@ static int start_program(char **command, sigset_t *mask)
if (pid < 0) {
pr_err("fork() failed: %m");
- return 1;
+ return 0;
}
if (!pid) {
@@ -949,7 +949,7 @@ static int start_program(char **command, sigset_t *mask)
free(s);
- return 0;
+ return pid;
}
static int create_config_files(struct config_file **configs)
@@ -1009,9 +1009,8 @@ static int script_run(struct script *script)
{
sigset_t mask, old_mask;
siginfo_t info;
- pid_t pid;
- int status, ret = 0;
- char ***command;
+ pid_t pid, *pids;
+ int i, num_commands, status, ret = 0;
if (create_config_files(script->configs))
return 1;
@@ -1028,8 +1027,14 @@ static int script_run(struct script *script)
return 1;
}
- for (command = script->commands; *command; command++) {
- if (start_program(*command, &old_mask)) {
+ for (num_commands = 0; script->commands[num_commands]; num_commands++)
+ ;
+
+ pids = calloc(num_commands, sizeof(*pids));
+
+ for (i = 0; i < num_commands; i++) {
+ pids[i] = start_program(script->commands[i], &old_mask);
+ if (!pids[i]) {
kill(getpid(), SIGTERM);
break;
}
@@ -1047,8 +1052,13 @@ static int script_run(struct script *script)
pr_info("received signal %d", info.si_signo);
- /* kill the process group */
- kill(0, SIGTERM);
+ /* kill all started processes */
+ for (i = 0; i < num_commands; i++) {
+ if (pids[i] > 0) {
+ pr_debug("killing process %d", pids[i]);
+ kill(pids[i], SIGTERM);
+ }
+ }
while ((pid = wait(&status)) >= 0) {
if (!WIFEXITED(status)) {
@@ -1062,6 +1072,8 @@ static int script_run(struct script *script)
}
}
+ free(pids);
+
if (remove_config_files(script->configs))
return 1;
--
2.1.0
2.1.0