diff options
Diffstat (limited to 'src/sysexec.c')
-rw-r--r-- | src/sysexec.c | 217 |
1 files changed, 31 insertions, 186 deletions
diff --git a/src/sysexec.c b/src/sysexec.c index 9a66e90..e7b17e1 100644 --- a/src/sysexec.c +++ b/src/sysexec.c @@ -80,41 +80,16 @@ void free_ptrptr(char** ptrptr) free(ptrptr); } -void child_list_init(child_list_t* list) +child_t* new_child(const char* script, char* const argv[], char* const evp[]) { - if(!list) - return; - - list->first_ = NULL; -} - -void child_list_clear(child_list_t* list) -{ - if(!list) - return; - - while(list->first_) { - child_list_element_t* tmp; - tmp = list->first_; - list->first_ = tmp->next_; - if(tmp->script_) - free(tmp->script_); - free(tmp); - } -} + child_t* new_child; -child_list_element_t* child_list_new(const char* script, char* const argv[], char* const evp[]) -{ - child_list_element_t* new_child; - - new_child = malloc(sizeof(child_list_element_t)); + new_child = malloc(sizeof(child_t)); if(!new_child) return NULL; - new_child->next_ = 0; new_child->pid_ = -1; new_child->err_fd_ = -1; - new_child->running_ = 0; new_child->script_ = strdup(script); if(!new_child->script_) { free(new_child); @@ -139,158 +114,43 @@ child_list_element_t* child_list_new(const char* script, char* const argv[], cha return new_child; } -child_list_element_t* child_list_add(child_list_t* list, const char* script, char* const argv[], char* const evp[]) -{ - if(!list) - return NULL; - - if(!list->first_) { - list->first_ = child_list_new(script, argv, evp); - return list->first_; - } - else { - child_list_element_t* tmp = list->first_; - while(tmp->next_) - tmp = tmp->next_; - - tmp->next_ = child_list_new(script, argv, evp); - return tmp->next_; - } -} - -void child_list_rm(child_list_t* list, child_list_element_t* child) +void free_child(child_t* child) { - if(!list || !child) - return; - - if(child == list->first_) { - list->first_ = list->first_->next_; - free_ptrptr(child->argv_); - free_ptrptr(child->evp_); - if(child->script_) - free(child->script_); - free(child); - return; - } - else { - child_list_element_t* tmp = list->first_; - while(tmp) { - if(tmp->next_ == child) { - tmp->next_ = tmp->next_->next_; - free_ptrptr(child->argv_); - free_ptrptr(child->evp_); - if(child->script_) - free(child->script_); - free(child); - return; - } - tmp = tmp->next_; - } - } -} - -void child_list_rm_pid(child_list_t* list, pid_t pid) -{ - if(!list) - return; - - child_list_element_t* tmp = NULL; - if(list->first_->pid_ == pid) { - tmp = list->first_; - list->first_ = list->first_->next_; - - free_ptrptr(tmp->argv_); - free_ptrptr(tmp->evp_); - if(tmp->script_) - free(tmp->script_); - free(tmp); + if(!child) return; - } - - child_list_element_t* prev = list->first_; - tmp = list->first_->next_; - while(tmp) { - if(tmp->pid_ == pid) { - prev->next_ = tmp->next_; - free_ptrptr(tmp->argv_); - free_ptrptr(tmp->evp_); - if(tmp->script_) - free(tmp->script_); - free(tmp); - return; - } - prev = tmp; - tmp = tmp->next_; - } -} - -child_list_element_t* child_list_find(child_list_t* list, pid_t pid) -{ - if(!list) - return NULL; - - child_list_element_t* tmp = list->first_; - while(tmp) { - if(tmp->pid_ == pid) - return tmp; - tmp = tmp->next_; - } - - return NULL; + free_ptrptr(child->argv_); + free_ptrptr(child->evp_); + if(child->script_) + free(child->script_); + if(child->err_fd_ >= 0) close(child->err_fd_); + free(child); } -int child_list_num_running(child_list_t* list) -{ - int num = 0; - - if(!list) - return 0; - - child_list_element_t* tmp = list->first_; - for(;tmp;tmp=tmp->next_) - if(tmp->running_) num++; - - return num; -} - -int rh_exec(const char* script, char* const argv[], char* const evp[], child_list_t* child_lst, options_t* opt) +child_t* rh_exec(const char* script, char* const argv[], char* const evp[]) { if(!script) - return -1; + return NULL; - child_list_element_t* child = child_list_add(child_lst, script, argv, evp); + child_t* child = new_child(script, argv, evp); if(!child) - return -2; - - if(child_list_num_running(child_lst) >= opt->max_children_) { - log_printf(INFO, "deferring script execution '%s'", script); - return 0; - } - - int ret = rh_exec_child(child); - if(ret) - child_list_rm(child_lst, child); - - return ret; -} - -int rh_exec_child(child_list_element_t* child) -{ - if(!child || child->pid_ != -1) - return -1; + return NULL; int pipefd[2]; if(pipe(pipefd) == -1) { - log_printf(ERROR, "executing script '%s' failed: pipe() error: %s", child->script_, strerror(errno)); - return -1; + log_printf(ERROR, "executing script '%s' failed: pipe() error: %s", child->script_, strerror(errno)); // TODO: thread safe strerror + free_child(child); + return NULL; } pid_t pid; pid = fork(); if(pid == -1) { - log_printf(ERROR, "executing script '%s' failed: fork() error: %s", child->script_, strerror(errno)); - return -1; + log_printf(ERROR, "executing script '%s' failed: fork() error: %s", child->script_, strerror(errno)); // TODO: thread safe strerror + close(pipefd[0]); + close(pipefd[1]); + free_child(child); + return NULL; } if(!pid) { @@ -318,28 +178,21 @@ int rh_exec_child(child_list_element_t* child) child->pid_ = pid; child->err_fd_ = pipefd[0]; - child->running_ = 1; log_printf(INFO, "called script '%s' with pid %d", child->script_, child->pid_); - return 0; + return child; } -int rh_waitpid(child_list_t* child_lst, options_t* opt) +int rh_waitpid(child_t* child, int* status_return) { int status = 0; - pid_t pid = waitpid(-1, &status, WNOHANG); + pid_t pid = waitpid(child->pid_, &status, WNOHANG); if(!pid || (pid < 0 && errno == ECHILD)) return 0; if(pid < 0) { - log_printf(ERROR, "waitpid returned with error: %s", strerror(errno)); - return pid; - } - - child_list_element_t* child = child_list_find(child_lst, pid); - if(!child) { - log_printf(ERROR, "waitpid returned unknown child pid (%d)", pid); - return 0; + log_printf(ERROR, "waitpid returned with error: %s", strerror(errno)); // TODO: thread safe strerror + return pid; } fd_set rfds; @@ -349,9 +202,7 @@ int rh_waitpid(child_list_t* child_lst, options_t* opt) if(select(child->err_fd_+1, &rfds, NULL, NULL, &tv) == 1) { int err = 0; if(read(child->err_fd_, (void*)(&err), sizeof(err)) >= sizeof(err)) { - log_printf(INFO, "script '%s' exec() error: %s", child->script_, strerror(err)); - close(child->err_fd_); - child_list_rm_pid(child_lst, pid); + log_printf(INFO, "script '%s' exec() error: %s", child->script_, strerror(err)); // TODO: thread safe strerror return -1; } } @@ -362,13 +213,7 @@ int rh_waitpid(child_list_t* child_lst, options_t* opt) else log_printf(INFO, "executing script '%s' (pid %d): unkown error", child->script_, child->pid_); - close(child->err_fd_); - - child_list_rm_pid(child_lst, pid); + if(status_return) *status_return = status; - if(child_list_num_running(child_lst) < opt->max_children_) - rh_exec_child(child_list_find(child_lst, -1)); - - return status; + return 1; } - |