diff options
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/file_list.c | 24 | ||||
-rw-r--r-- | src/file_list.h | 5 | ||||
-rw-r--r-- | src/sysexec.c | 217 | ||||
-rw-r--r-- | src/sysexec.h | 26 | ||||
-rw-r--r-- | src/writer.c | 2 |
6 files changed, 59 insertions, 216 deletions
diff --git a/src/Makefile b/src/Makefile index 9651ce6..0e989ac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,6 +35,7 @@ C_OBJS := log.o \ string_list.o \ writer.o \ file_list.o \ + sysexec.o \ rharchive.o C_SRCS := $(C_OBJS:%.o=%.c) diff --git a/src/file_list.c b/src/file_list.c index 00b8b12..bced939 100644 --- a/src/file_list.c +++ b/src/file_list.c @@ -45,6 +45,7 @@ static void delete_file(void* element) log_printf(INFO, "removing/closing file '%s' -> %d", deletee->path_, deletee->fd_); if(deletee->path_) free(deletee->path_); if(deletee->fd_ >= 0) close(deletee->fd_); + if(deletee->pp_child_) free_child(deletee->pp_child_); } int file_list_init(file_list_t* list) @@ -85,6 +86,7 @@ file_t* file_list_add(file_list_t* list, struct tm* time, const char* type, cons log_printf(INFO, "%s filename is: %s(.?)", type, tmp->path_); tmp->fd_ = FILE_CLOSED; tmp->mode_ = mode; + tmp->pp_child_ = NULL; g_mutex_lock(list->mutex_); if(slist_add(&(list->list_), tmp) == NULL) { @@ -117,7 +119,7 @@ int file_list_remove(file_list_t* list, int fd) return 0; } -int file_list_call_post_process(file_list_t* list, int fd) +int file_list_call_post_process(file_list_t* list, int fd, const char* script) { if(!list || !(list->mutex_)) return -1; @@ -129,7 +131,13 @@ int file_list_call_post_process(file_list_t* list, int fd) log_printf(INFO, "calling post processing for '%s'", ((file_t*)tmp->data_)->path_); close(((file_t*)tmp->data_)->fd_); ((file_t*)tmp->data_)->fd_ = FILE_POST_PROCESS; - // ((file_t*)tmp->data_)->pp_pid_ = ... + + char* const argv[] = { script, ((file_t*)tmp->data_)->path_, NULL }; + char* const evp[] = { NULL }; + ((file_t*)tmp->data_)->pp_child_ = rh_exec(script, argv, evp); + if(!((file_t*)tmp->data_)->pp_child_) + slist_remove(&(list->list_), tmp->data_); + break; } tmp = tmp->next_; @@ -148,12 +156,14 @@ int file_list_waitpid(file_list_t* list) slist_element_t* tmp = list->list_.first_; while(tmp) { if(((file_t*)tmp->data_)->fd_ == FILE_POST_PROCESS) { - // int status; - // int ret = waitpid(((file_t*)tmp->data_)->pp_pid_, &status, WHOHANG); - // ... - slist_remove(&(list->list_), tmp->data_); + int ret = rh_waitpid(((file_t*)tmp->data_)->pp_child_, NULL); + file_t* deletee = tmp->data_; + tmp = tmp->next_; + if(ret) + slist_remove(&(list->list_), deletee); } - tmp = tmp->next_; + else + tmp = tmp->next_; } g_mutex_unlock(list->mutex_); diff --git a/src/file_list.h b/src/file_list.h index 92bfbf0..b33ee51 100644 --- a/src/file_list.h +++ b/src/file_list.h @@ -31,6 +31,7 @@ #include <glib.h> #include "slist.h" +#include "sysexec.h" #define FILE_CLOSED -1 #define FILE_POST_PROCESS -2 @@ -39,7 +40,7 @@ struct file_struct { int fd_; char* path_; mode_t mode_; - pid_t pp_pid_; + child_t* pp_child_; }; typedef struct file_struct file_t; @@ -53,7 +54,7 @@ int file_list_init(file_list_t* list); void file_list_clear(file_list_t* list); file_t* file_list_add(file_list_t* list, struct tm* time, const char* type, const char* format, const char* dir, mode_t mode); int file_list_remove(file_list_t* list, int fd); -int file_list_call_post_process(file_list_t* list, int fd); +int file_list_call_post_process(file_list_t* list, int fd, const char* script); int file_list_waitpid(file_list_t* list); int open_file(file_t* file); 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; } - diff --git a/src/sysexec.h b/src/sysexec.h index 481bc9d..0ec9829 100644 --- a/src/sysexec.h +++ b/src/sysexec.h @@ -28,33 +28,19 @@ #include <sys/types.h> #include "options.h" -struct child_list_element_struct { +struct child_struct { pid_t pid_; char* script_; int err_fd_; - int running_; char** argv_; char** evp_; - struct child_list_element_struct* next_; }; -typedef struct child_list_element_struct child_list_element_t; +typedef struct child_struct child_t; -struct child_list_struct { - child_list_element_t* first_; -}; -typedef struct child_list_struct child_list_t; - -void child_list_init(child_list_t* list); -void child_list_clear(child_list_t* list); -child_list_element_t* child_list_new(const char* script, char* const argv[], char* const evp[]); -child_list_element_t* child_list_add(child_list_t* list, const char* script, char* const argv[], char* const evp[]); -void child_list_rm(child_list_t* list, child_list_element_t* child); -void child_list_rm_pid(child_list_t* list, pid_t pid); -child_list_element_t* child_list_find(child_list_t* list, pid_t pid); -int child_list_num_running(child_list_t* list); +child_t* new_child(const char* script, char* const argv[], char* const evp[]); +void free_child(child_t* child); -int rh_exec(const char* script, char* const argv[], char* const evp[], child_list_t* child_lst, options_t* opt); -int rh_exec_child(child_list_element_t* child); -int rh_waitpid(child_list_t* child_lst, options_t* opt); +child_t* rh_exec(const char* script, char* const argv[], char* const evp[]); +int rh_waitpid(child_t* child, int* status); #endif diff --git a/src/writer.c b/src/writer.c index 0459b19..16fa23e 100644 --- a/src/writer.c +++ b/src/writer.c @@ -87,7 +87,7 @@ static void fdremoved_cb(GstElement* sink, gint fd, gpointer data) writer_t *writer = (writer_t*)data; if(writer->post_process_) - file_list_call_post_process(&(writer->files_), fd); + file_list_call_post_process(&(writer->files_), fd, writer->post_process_); else file_list_remove(&(writer->files_), fd); } |