From 0de355ebbf6d9eb9ab673da22eb18cbb01d005f8 Mon Sep 17 00:00:00 2001 From: scratko Date: Mon, 28 Jul 2025 01:19:54 +0300 Subject: Revise subshell execution and terminal group handling find_end_subshell_before_cur_pos() now accounts for offset caused by two-character tokens (|| and &&). Added many explanatory comments. Modified or removed some fields of the params structure that affected pipe and subshell behavior (e.g., pgid for multiple processes, file descriptors). Changed logic for setting the current terminal process group. Removed side effect in the conditional operator inside special_token_handling() that made the code harder to read. Removed the functions identify_general_pgid() and identify_general_pipe_pgid(). Replaced them with a single function: set_foreground_group(). make_pipeline() now also checks for subshell_before before executing the pipeline. Major changes to the functions make_pipeline(), make_subshell(), and run_external_program(). Subshell exit code now depends on the success or failure of executed programs when using logical operators (|| and &&). --- lexical_analysis.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'lexical_analysis.c') diff --git a/lexical_analysis.c b/lexical_analysis.c index eab4390..8196403 100644 --- a/lexical_analysis.c +++ b/lexical_analysis.c @@ -46,10 +46,11 @@ int is_empty_word(int ch, struct param_type params) params.empty_word_flag; } -static int find_end_subshell_before_cur_pos(struct readline_type *readline) +static int find_end_subshell_before_cur_pos(struct readline_type *readline, + int offset) { int i; - for(i = readline->considered_index-1; i >= 0; --i) { + for(i = readline->considered_index-1-offset; i >= 0; --i) { if(readline->arr[i] == ' ') continue; break; @@ -60,19 +61,27 @@ static int find_end_subshell_before_cur_pos(struct readline_type *readline) int command_execution_condition(struct param_type *params, struct readline_type *readline) { + /* + * return 0 when + * ()&& + * ()|| + * (); + * ()& + * Nothing to handling cause empty word + */ if(params->tokens == and || params->tokens == or) { - if(find_end_subshell_before_cur_pos(readline)) + if(find_end_subshell_before_cur_pos(readline, 2)) return 0; } if(params->tokens == next_command) { - if(find_end_subshell_before_cur_pos(readline)) + if(find_end_subshell_before_cur_pos(readline, 1)) return 0; } if(params->tokens == '&') { - if(find_end_subshell_before_cur_pos(readline)) + if(find_end_subshell_before_cur_pos(readline, 1)) return 0; } - if(params->tokens == '(' && params->pipeline) + if(params->tokens == start_subshell && params->pipeline) return 1; return @@ -154,6 +163,10 @@ int stream_redirect_tokens(struct w_queue *word_chain, next_ch = readline->arr[readline->considered_index + 1]; if(is_redirect_token(ch, next_ch)) { + /* + * The word will be added because the token has not yet been + * set in the redirect. + */ add_word_or_filename(word_chain, tmp_word, params); if(params->wrong_command) @@ -189,7 +202,10 @@ int pipeline_token_processing(struct w_queue *word_chain, struct dynamic_array *tmp_word, struct param_type *params) { - /* pipeline after subshell */ + /* + * pipeline after subshell + * no words to add to cmdlines + */ if(tmp_word->last_element_index == -1 && params->tokens == start_subshell) { params->tokens = '|'; params->pipeline = 1; @@ -245,6 +261,10 @@ int special_tokens(struct w_queue *word_chain, struct c_queue *cmdlines, next_ch = readline->arr[readline->considered_index + 1]; if(is_special_token(*ch, next_ch)) { + /* + * if were tokens == ‘<’ or ‘>’ or ‘>>’, then the filename is added + * else just word + */ add_word_or_filename(word_chain, tmp_word, params); stop_by_previous_effect_tokens(params); -- cgit v1.2.3