summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2015-09-17 17:15:55 +0200
committerChristian Pointner <equinox@spreadspace.org>2015-09-17 17:15:55 +0200
commit5f594bfbcb2d2bd132fb6eb006fe9dccc7ee5344 (patch)
treef4948f9785093cfda04fb00c578028390f5e9509
parentmove children to own process group and kill the whole group (diff)
fixed race condition between killing processes
-rw-r--r--src/sysexec.c23
-rw-r--r--src/sysexec.h4
2 files changed, 20 insertions, 7 deletions
diff --git a/src/sysexec.c b/src/sysexec.c
index 782b10d..6f606ff 100644
--- a/src/sysexec.c
+++ b/src/sysexec.c
@@ -98,6 +98,10 @@ void child_list_clear(child_list_t* list)
list->first_ = tmp->next_;
if(tmp->script_)
free(tmp->script_);
+ if(tmp->state_ == RUNNING) {
+ pid_t pgid = getpgid(tmp->pid_);
+ kill(pgid * -1, SIGKILL);
+ }
free(tmp);
}
}
@@ -113,7 +117,7 @@ child_list_element_t* child_list_new(const char* script, char* const argv[], cha
new_child->next_ = 0;
new_child->pid_ = -1;
new_child->err_fd_ = -1;
- new_child->running_ = 0;
+ new_child->state_ = NEW;
new_child->script_ = strdup(script);
if(!new_child->script_) {
free(new_child);
@@ -248,7 +252,7 @@ int child_list_num_running(child_list_t* list)
child_list_element_t* tmp = list->first_;
for(;tmp;tmp=tmp->next_)
- if(tmp->running_) num++;
+ if(tmp->state_ == RUNNING) num++;
return num;
}
@@ -258,9 +262,16 @@ void child_list_kill_oldest(child_list_t* list)
if(!list || !list->first_)
return;
- pid_t pgid = getpgid(list->first_->pid_);
- log_printf(DEBUG, "sending KILL signal to child %d with process group id %d", list->first_->pid_, pgid);
- kill(pgid * -1, SIGKILL);
+ child_list_element_t* tmp = list->first_;
+ for(;tmp;tmp=tmp->next_) {
+ if(tmp->state_ == RUNNING) {
+ pid_t pgid = getpgid(tmp->pid_);
+ log_printf(DEBUG, "sending KILL signal to child %d with process group id %d", list->first_->pid_, pgid);
+ kill(pgid * -1, SIGKILL);
+ tmp->state_ = KILLED;
+ break;
+ }
+ }
}
int rh_exec(const char* script, char* const argv[], char* const evp[], child_list_t* child_lst, options_t* opt)
@@ -337,7 +348,7 @@ int rh_exec_child(child_list_element_t* child)
child->pid_ = pid;
child->err_fd_ = pipefd[0];
- child->running_ = 1;
+ child->state_ = RUNNING;
log_printf(INFO, "called script '%s' with pid %d", child->script_, child->pid_);
diff --git a/src/sysexec.h b/src/sysexec.h
index 560a70f..4345a15 100644
--- a/src/sysexec.h
+++ b/src/sysexec.h
@@ -25,11 +25,13 @@
#include <sys/types.h>
#include "options.h"
+typedef enum { NEW, RUNNING, KILLED } child_state_t;
+
struct child_list_element_struct {
pid_t pid_;
char* script_;
int err_fd_;
- int running_;
+ child_state_t state_;
char** argv_;
char** evp_;
struct child_list_element_struct* next_;