diff options
author | scratko <m@scratko.xyz> | 2025-07-28 01:19:54 +0300 |
---|---|---|
committer | scratko <m@scratko.xyz> | 2025-07-28 01:19:54 +0300 |
commit | 0de355ebbf6d9eb9ab673da22eb18cbb01d005f8 (patch) | |
tree | 197d81a0d4df5c728217cc3ebaa255678d621b86 /lexical_analysis.c | |
parent | 765c24a70be0b968a08bbd3c26b1644843863fcd (diff) | |
download | shell-0de355ebbf6d9eb9ab673da22eb18cbb01d005f8.tar.gz shell-0de355ebbf6d9eb9ab673da22eb18cbb01d005f8.tar.bz2 shell-0de355ebbf6d9eb9ab673da22eb18cbb01d005f8.zip |
Revise subshell execution and terminal group handlingshell-VII
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 &&).
Diffstat (limited to 'lexical_analysis.c')
-rw-r--r-- | lexical_analysis.c | 34 |
1 files changed, 27 insertions, 7 deletions
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); |