From 8bcfbe6a15f6195c3501b9bde633081da67179d1 Mon Sep 17 00:00:00 2001 From: scratko Date: Wed, 5 Jun 2024 18:06:48 +0300 Subject: Signal handler Moving zombie process cleanup to the signal handler. --- shell.c | 85 ++++++++++++++++++++++++++++++----------------------------------- 1 file changed, 39 insertions(+), 46 deletions(-) diff --git a/shell.c b/shell.c index 9ce5a32..d3b96b3 100644 --- a/shell.c +++ b/shell.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include enum modes { word_separation, whole_word }; enum { @@ -53,6 +55,20 @@ static void print_error() fprintf(stderr, "Error: unmatched quotes\n"); } +/* remove background zombie processes */ +static void handler(int signal) +{ + int save_errno = errno; + int pid; + + if(signal == SIGCHLD) { + do { + pid = wait4(-1, NULL, WNOHANG, NULL); + } while(pid > 0); + } + errno = save_errno; +} + static void init_params(struct param_type *params, enum modes *current_mode) { params->is_word = 0; @@ -294,16 +310,7 @@ static int start_escape_sequence(int ch, struct param_type params) static int excessive_words(int ch, const struct param_type *params) { int next_ch; -#if 0 - if(filename_waiting(params)) - return - (params->tokens == '<' && params->streams.input_stream != NULL) || - (params->tokens == '>' && params->streams.output_stream !=NULL) || - (params->tokens == append && - params->streams.output_stream_to_append != NULL); - else - return 0; -#endif + if(filename_waiting(params)) { if(ch == new_line) return 0; @@ -320,23 +327,6 @@ static int excessive_words(int ch, const struct param_type *params) return 0; } -#if 0 -static void print_word(char *word) -{ - putchar('['); - while(*word) { - putchar(*word); - ++word; - } - printf("]\n"); -} - -static void print_line(const struct queue *word_chain) -{ - queue_processing(word_chain, print_word); -} -#endif - static char** create_cmdline(const struct queue *word_chain, int word_counter) { @@ -382,14 +372,6 @@ static void clean_up_memory(struct queue *word_chain, char **cmdline, clear_filename(params); } -static void clean_up_zombie_process() -{ - int pid; - do { - pid = wait4(-1, NULL, WNOHANG, NULL); - } while(pid > 0); -} - static void open_files(const struct param_type *params, int *input_fd, int *output_fd) { @@ -427,11 +409,13 @@ static void run_external_program(struct queue *word_chain, struct param_type *params) { int pid, wait_pid, result, input_fd, output_fd; + input_fd = 0; + output_fd = 0; + if(word_chain->first == NULL) { fprintf(stderr, "empty command\n"); return; } - if(is_stream_redirection_set(params)) open_files(params, &input_fd, &output_fd); @@ -451,7 +435,16 @@ static void run_external_program(struct queue *word_chain, perror("fork error"); exit(1); } - /* child process */ + if(params->tokens == '&') + /* zombie process termination on signal */ + signal(SIGCHLD, handler); + else + /* the parent process will wait for the process to complete; + default signal disposition + */ + signal(SIGCHLD, SIG_DFL); + + /* child process */ if(pid == 0) { if(is_stream_redirection_set(params)) change_streams(input_fd, output_fd); @@ -460,18 +453,19 @@ static void run_external_program(struct queue *word_chain, perror(cmdline[0]); exit(1); } - /* parent process */ + /* parent process */ close_files(input_fd, output_fd); clean_up_memory(word_chain, cmdline, params); - /* waiting for forground process */ - if(params->tokens != '&') { + /* waiting for forground process by pid*/ + if(params->tokens != '&') do { wait_pid = wait(&result); } while(wait_pid != pid); - } else - clean_up_zombie_process(); + + /* return of background process zombie cleanup */ + signal(SIGCHLD, handler); } } @@ -521,9 +515,9 @@ static int is_empty_word(int ch, struct param_type params) } static void word_separation_processing(int ch, struct param_type *params, - enum modes *current_mode, - struct queue *word_chain, - struct dynamic_array *tmp_word) + enum modes *current_mode, + struct queue *word_chain, + struct dynamic_array *tmp_word) { /* could be a marker for the beginning of a blank word */ params->stored_symbol = ch; @@ -636,7 +630,6 @@ int main() init_params(¶ms, ¤t_mode); show_invitation(); while((ch = getchar()) != EOF) { - clean_up_zombie_process(); if(ch == new_line) command_processing(¶ms, ¤t_mode, &word_chain, &tmp_word, ch); -- cgit v1.2.3