diff --git a/Makefile b/Makefile index c73d812..7888311 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ LIBFT := $(PATH_LIBFT)libft.a PATH_SRCS += srcs/ PATH_SRCS += srcs/minishell_main_routine +PATH_SRCS += srcs/signals_handling PATH_SRCS += srcs/exit_routines PATH_SRCS += srcs/user_interface PATH_SRCS += srcs/history @@ -42,7 +43,6 @@ SRCS += exit_shell_routine.c # scrs/user_interface -SRCS += signals.c SRCS += prompt.c # srcs/history @@ -88,6 +88,7 @@ SRCS += set_variable_to_environment.c # srcs/environment_building SRCS += build_environment.c +SRCS += build_minimal_environment.c # srcs/semantic_analysis @@ -106,6 +107,9 @@ SRCS += get_command_name.c SRCS += is_builtin.c SRCS += delete_command_pipeline.c SRCS += setup_pipe.c +SRCS += is_delimiter.c +SRCS += ensure_stdin_is_open.c +SRCS += heredoc_interruption_routine.c # srcs/command_interpretation @@ -156,6 +160,14 @@ SRCS += expander_exit.c SRCS += erase_quotes.c SRCS += expand_variable_utils.c +# srcs/signals_handling + +SRCS += setup_main_process_signals_handling.c +SRCS += setup_command_mode_signals.c +SRCS += setup_heredoc_signals_handling.c +#SRCS += setup_execution_mode_signal_handling.c +SRCS += signals.c + # srcs/exit_status SRCS += set_exit_status.c diff --git a/includes/environment.h b/includes/environment.h index 6210620..d5e0cbb 100644 --- a/includes/environment.h +++ b/includes/environment.h @@ -48,6 +48,7 @@ typedef struct s_variable t_variable_list *get_environment(void); t_status build_environment(char **variables); +t_status build_minimal_environment(void); t_status set_variable_from_keyvalue_to_environment( const char *keyvalue, bool make_it_exportable, t_variable_list *environment); diff --git a/includes/expander.h b/includes/expander.h index 13040ef..c7f984e 100644 --- a/includes/expander.h +++ b/includes/expander.h @@ -10,7 +10,10 @@ /* */ /* ************************************************************************** */ -#include "minishell.h" +#ifndef EXPANDER_H +# define EXPANDER_H + +# include "minishell.h" typedef enum e_quote_state { @@ -33,3 +36,5 @@ void change_quote_state(char quote, t_quote_state *quote_state); void expander_exit(void); void erase_quotes(t_token_list token_list); char *manage_return_cmd(t_lexem temp_expanded, t_lexem expanded_word); + +#endif \ No newline at end of file diff --git a/includes/lexing.h b/includes/lexing.h index f793aa6..0ab30cb 100644 --- a/includes/lexing.h +++ b/includes/lexing.h @@ -60,6 +60,7 @@ typedef struct s_token { t_lexem token_lexem; t_token_type token_type; + bool is_surrounded_by_quotes; } t_token; typedef t_token t_grammar_element; diff --git a/includes/minishell.h b/includes/minishell.h index 16fd87c..8405279 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -32,6 +32,11 @@ # include # include # include +# include + +// GLOBAL VARIABLE + +extern volatile sig_atomic_t g_received_signal; // DEFINES @@ -82,14 +87,13 @@ typedef enum e_new_line_status NO_NEW_LINE } t_new_line_status; -typedef int (*t_builtin)(t_command *current_command); +typedef int (*t_builtin)(t_command *current_command); // PROTOTYPES void display_minishell_header(void); int core_routine(t_minishell_context *minishell_context); int exit_shell_routine(void); -char *prompt_gets_user_input(void); t_lexing_status lexe_input(t_command_session *current_command); t_syntax_status parse_input(t_token_list token_list); t_command_pipeline semantic_analyzer(t_token_list token_list); @@ -148,4 +152,10 @@ int update_env_variables(char *old_pwd); void set_exit_status(int exit_status); int get_exit_status_value(void); +// SIGNALS HANDLING + +void setup_default_signals_handling(void); +void setup_command_mode_signals_handling(void); +void setup_heredoc_signals_handling(void); + #endif diff --git a/includes/semantic.h b/includes/semantic.h index 046f294..7904507 100644 --- a/includes/semantic.h +++ b/includes/semantic.h @@ -144,6 +144,12 @@ void delete_command_pipeline( t_command_pipeline *cmd_pipeline); void get_command_name(t_command *command); bool is_builtin(const char *command_name); +bool is_delimiter(const char *delimiter, + const char *line); +void ensure_stdin_is_open(void); +void heredoc_interruption_routine( + const char *delimiter, + int heredoc_lines); void print_arguments_list( t_command_args arguments_list); diff --git a/includes/user_interface.h b/includes/user_interface.h index 46bd55f..e14efaa 100644 --- a/includes/user_interface.h +++ b/includes/user_interface.h @@ -24,13 +24,18 @@ // DEFINES # define MSH_PROMPT "SDF$> " +# define HEREDOC_PROMPT "captain'hirdock>" # define CTRL_D 0 # define FAILURE -1 +# define MAIN_PROMPT 0 +# define SUBPROMPT 1 // PROTOTYPES -void signal_handler(int signum); -void received_signal(void); -void setup_signals(struct sigaction *sa); +//void signal_handler(int signum); +//void received_signal(void); +char *prompt_gets_user_input(bool is_subprompt); +void setup_main_prompt_signals_handling(void); +//void setup_signals(struct sigaction *sa); #endif diff --git a/srcs/builtins/cd/cd.c b/srcs/builtins/cd/cd.c index d4d4a14..55e8faf 100644 --- a/srcs/builtins/cd/cd.c +++ b/srcs/builtins/cd/cd.c @@ -30,7 +30,7 @@ static int change_directory(char *target) if (chdir(target) == -1) { free(target); - perror("chdir"); + perror("cd"); return (EXIT_FAILURE); } free(target); diff --git a/srcs/command_interpretation/close_command_pipeline.c b/srcs/command_interpretation/close_command_pipeline.c index 71837a2..9bcb7f2 100644 --- a/srcs/command_interpretation/close_command_pipeline.c +++ b/srcs/command_interpretation/close_command_pipeline.c @@ -28,6 +28,8 @@ int close_command_pipeline(t_command_pipeline cmd_pipeline, { if (WIFEXITED(last_command_status)) exit_status = WEXITSTATUS(last_command_status); + else if (WIFSTOPPED(last_command_status)) + exit_status = 128 + WSTOPSIG(last_command_status); else if (WIFSIGNALED(last_command_status)) exit_status = (128 + WTERMSIG(last_command_status)); else diff --git a/srcs/command_interpretation/command_interpreter.c b/srcs/command_interpretation/command_interpreter.c index c4bfb65..ffd87c3 100644 --- a/srcs/command_interpretation/command_interpreter.c +++ b/srcs/command_interpretation/command_interpreter.c @@ -44,10 +44,12 @@ static void launch_command(t_minishell_context *minishell_context, command->command_pid = command_process_pid; if (command_process_pid > 0) { + setup_default_signals_handling(); main_process_io_management(command); } if (command_process_pid == 0) { + setup_command_mode_signals_handling(); command_process(minishell_context, command); } } @@ -78,6 +80,7 @@ int command_pipeline_interpreter(t_minishell_context *minishell_context) t_command_pipeline current_command; pid_t last_command_pid; + setup_default_signals_handling(); cmd_pipeline = minishell_context->command_session.command_pipeline; current_command = cmd_pipeline; while (current_command != NULL) diff --git a/srcs/command_interpretation/command_path_manager.c b/srcs/command_interpretation/command_path_manager.c index 09dbe4c..deceb47 100644 --- a/srcs/command_interpretation/command_path_manager.c +++ b/srcs/command_interpretation/command_path_manager.c @@ -31,6 +31,8 @@ static t_command_status check_complete_absolute_path(t_command *command, static t_command_status check_uncomplete_absolute_path(t_command *command, char **command_env) { + if (ft_getenv("PATH", command_env) == NULL) + return (INVALID_COMMAND); return (build_complete_path(command, command_env)); } diff --git a/srcs/command_interpretation/command_process.c b/srcs/command_interpretation/command_process.c index e0494a7..93d28b8 100644 --- a/srcs/command_interpretation/command_process.c +++ b/srcs/command_interpretation/command_process.c @@ -61,6 +61,14 @@ void close_command_process_unused_fds(t_minishell_context *minishell_context, } } +static void undefined_command_process(t_minishell_context *minishell_context) +{ + const int exit_value = get_exit_status_value(); + + clean_command_process(minishell_context); + exit(exit_value); +} + void command_process(t_minishell_context *minishell_context, t_command *command) { @@ -68,12 +76,11 @@ void command_process(t_minishell_context *minishell_context, if (setup_command_redirections(command) == EXIT_FAILURE) { clean_command_process(minishell_context); - exit(FAILURE); + exit(EXIT_FAILURE); } if (command->command_nature == UNDEFINED) { - clean_command_process(minishell_context); - exit(SUCCESS); + undefined_command_process(minishell_context); } if (command->command_nature == BUILTIN) execute_builtin(minishell_context, command, BUILTIN_IN_PIPELINE); diff --git a/srcs/command_interpretation/execute_command.c b/srcs/command_interpretation/execute_command.c index 7351255..b56254c 100644 --- a/srcs/command_interpretation/execute_command.c +++ b/srcs/command_interpretation/execute_command.c @@ -44,6 +44,8 @@ static t_command_status get_command_validity(t_command *command, const t_path_type command_path_type = get_path_type( command->command_name); + if (*(command->command_name) == '\0') + return (INVALID_COMMAND); return (command_path_manager(command, command_env, command_path_type)); } @@ -61,7 +63,7 @@ t_command_status execute_command(t_command *command) execve(command->command_binary_path, command_arguments, command_environment); } - ft_dprintf(STDERR_FILENO, "minishell: command not found: %s\n", + ft_dprintf(STDERR_FILENO, "minishell: %s: command not found\n", command->command_args->content); clean_command_attributes(command_arguments, command_environment); return (INVALID_COMMAND); diff --git a/srcs/environment_building/build_minimal_environment.c b/srcs/environment_building/build_minimal_environment.c new file mode 100644 index 0000000..1d478cb --- /dev/null +++ b/srcs/environment_building/build_minimal_environment.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* build_minimal_environment.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/15 18:58:08 by tchobert #+# #+# */ +/* Updated: 2025/02/15 18:58:17 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_status set_pwd(void) +{ + char *pwd_variable; + char cwd[PATH_MAX]; + + if (getcwd(cwd, PATH_MAX) == NULL) + { + perror("getcwd"); + return (PROCESS_FAILURE); + } + if (ft_asprintf(&pwd_variable, "PWD=%s", cwd) == -1) + return (PROCESS_FAILURE); + if (set_variable_from_keyvalue(pwd_variable, EXPORTABLE) == PROCESS_FAILURE) + return (PROCESS_FAILURE); + return (PROCESS_SUCCESS); +} + +t_status build_minimal_environment(void) +{ + if (set_variable_from_keyvalue("SHLVL=1", EXPORTABLE) == PROCESS_FAILURE) + return (PROCESS_FAILURE); + return (set_pwd()); +} diff --git a/srcs/exit_routines/exit_shell_routine.c b/srcs/exit_routines/exit_shell_routine.c index 6a2f8af..d63f799 100644 --- a/srcs/exit_routines/exit_shell_routine.c +++ b/srcs/exit_routines/exit_shell_routine.c @@ -14,7 +14,9 @@ int exit_shell_routine(void) { + const int exit_value = get_exit_status_value(); + delete_variables_list(); - printf("exit\n"); - exit (EXIT_SUCCESS); + ft_putstr_fd("exit\n", STDERR_FILENO); + exit(exit_value); } diff --git a/srcs/expander/erase_quotes.c b/srcs/expander/erase_quotes.c index 31ef414..2f87224 100644 --- a/srcs/expander/erase_quotes.c +++ b/srcs/expander/erase_quotes.c @@ -12,6 +12,23 @@ #include "minishell.h" +static bool is_surrounded_by_quotes(char *word) +{ + size_t word_len; + + if (word == NULL || *word == '\0') + return (false); + word_len = ft_strlen(word); + if (word_len < 2) + return (false); + if (*word == '\"' && word[word_len -1] == '\"') + return (true); + else if (*word == '\'' && word[word_len -1] == '\'') + return (true); + else + return (false); +} + static char *erase_quotes_in_word(t_lexem word, t_quote_state *quote_state) { size_t i; @@ -51,6 +68,8 @@ void erase_quotes(t_token_list token_list) token = current_token->content; if (token->token_type == WORD) { + token->is_surrounded_by_quotes + = is_surrounded_by_quotes(token->token_lexem); expanded_token = erase_quotes_in_word(token->token_lexem, "e_state); free(token->token_lexem); diff --git a/srcs/minishell_main_routine/core_routine.c b/srcs/minishell_main_routine/core_routine.c index ac527b6..14f37ae 100644 --- a/srcs/minishell_main_routine/core_routine.c +++ b/srcs/minishell_main_routine/core_routine.c @@ -52,8 +52,9 @@ int core_routine(t_minishell_context *minishell_context) { while (MSH_LOOP) { + g_received_signal = 0; minishell_context->command_session.user_input_line - = prompt_gets_user_input(); + = prompt_gets_user_input(MAIN_PROMPT); current_loop_process(minishell_context); clean_current_loop_context(minishell_context); } diff --git a/srcs/minishell_main_routine/main.c b/srcs/minishell_main_routine/main.c index 36776c6..a126cb8 100644 --- a/srcs/minishell_main_routine/main.c +++ b/srcs/minishell_main_routine/main.c @@ -14,21 +14,37 @@ #ifndef TEST_MODE +volatile sig_atomic_t g_received_signal = 0; + +static void environment_initialisation_failure_exit_process(void) +{ + ft_dprintf(STDERR_FILENO, "Fatal error while initializing minishell's" + " environment. Aborting\n"); + exit(EXIT_FAILURE); +} + static int launch_shell(char **env) { t_minishell_context minishell_context; - struct sigaction sa; display_minishell_header(); + setup_default_signals_handling(); ft_bzero(&minishell_context, sizeof(minishell_context)); - if (build_environment(env) == PROCESS_FAILURE) + if (*env != NULL) + { + if (build_environment(env) == PROCESS_FAILURE) + { + environment_initialisation_failure_exit_process(); + } + } + else { - ft_dprintf(STDERR_FILENO, "Fatal error while initializing minishell's" - " environment\n"); - exit(EXIT_FAILURE); + if (build_minimal_environment() == PROCESS_FAILURE) + { + environment_initialisation_failure_exit_process(); + } } - set_exit_status(0); - setup_signals(&sa); + set_exit_status(EXIT_SUCCESS); return (core_routine(&minishell_context)); } diff --git a/srcs/semantic_analysis/assignation_checker.c b/srcs/semantic_analysis/assignation_checker.c index b541cb9..aba5658 100644 --- a/srcs/semantic_analysis/assignation_checker.c +++ b/srcs/semantic_analysis/assignation_checker.c @@ -41,7 +41,7 @@ t_assignation_status assignation_checker(char *assignation) i = 1; while (probable_key[i] != '\0') { - if (ft_isalnum(probable_key[i]) == false) + if (ft_isalnum(probable_key[i]) == false && probable_key[i] != '_') { free(probable_key); return (INVALID_ASSIGNATION); diff --git a/srcs/semantic_analysis/ensure_stdin_is_open.c b/srcs/semantic_analysis/ensure_stdin_is_open.c new file mode 100644 index 0000000..6ac03ba --- /dev/null +++ b/srcs/semantic_analysis/ensure_stdin_is_open.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ensure_stdin_is_open.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/14 19:58:56 by tchobert #+# #+# */ +/* Updated: 2025/02/14 19:59:05 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ensure_stdin_is_open(void) +{ + const int tty_fd = open("/dev/tty", O_RDONLY); + + if (tty_fd != -1) + { + dup2(tty_fd, STDIN_FILENO); + close(tty_fd); + } +} diff --git a/srcs/semantic_analysis/heredoc_interruption_routine.c b/srcs/semantic_analysis/heredoc_interruption_routine.c new file mode 100644 index 0000000..e927b37 --- /dev/null +++ b/srcs/semantic_analysis/heredoc_interruption_routine.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc_interruption_routine.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/14 20:00:29 by tchobert #+# #+# */ +/* Updated: 2025/02/14 20:00:42 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void heredoc_interruption_routine(const char *delimiter, int heredoc_lines) +{ + if (heredoc_lines == 0) + heredoc_lines = 1; + ft_dprintf(STDERR_FILENO, "minishell: warning: here-document " + "at line %d delimited by end-of-file (wanted `%s')\n", + heredoc_lines, delimiter); +} diff --git a/srcs/semantic_analysis/is_delimiter.c b/srcs/semantic_analysis/is_delimiter.c new file mode 100644 index 0000000..7a3d1e5 --- /dev/null +++ b/srcs/semantic_analysis/is_delimiter.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_delimiter.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/14 19:57:18 by tchobert #+# #+# */ +/* Updated: 2025/02/14 19:57:30 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +bool is_delimiter(const char *delimiter, const char *line) +{ + const size_t delimiter_size = ft_strlen(delimiter); + const size_t line_size = ft_strlen(line); + + return (delimiter_size == line_size && ft_strcmp(line, delimiter) == 0); +} diff --git a/srcs/semantic_analysis/save_opening_error.c b/srcs/semantic_analysis/save_opening_error.c index 788c43b..101a782 100644 --- a/srcs/semantic_analysis/save_opening_error.c +++ b/srcs/semantic_analysis/save_opening_error.c @@ -16,18 +16,18 @@ void save_opening_error(t_command *current_command, const char *file_name) { if (errno == ENOENT) ft_asprintf(¤t_command->opening_failure_msg, - "minishell: %s: No such file or directory\n", file_name); + "minishell: %s: No such file or directory", file_name); else if (errno == EACCES) ft_asprintf(¤t_command->opening_failure_msg, - "minishell: %s: Permission denied\n", file_name); + "minishell: %s: Permission denied", file_name); else if (errno == EMFILE || errno == ENFILE) ft_asprintf(¤t_command->opening_failure_msg, - "minishell: %s: Too many open files\n", file_name); + "minishell: %s: Too many open files", file_name); else if (errno == EISDIR) ft_asprintf(¤t_command->opening_failure_msg, - "minishell: %s: Is a directory\n", file_name); + "minishell: %s: Is a directory", file_name); else ft_asprintf(¤t_command->opening_failure_msg, - "minishell: %s: failed to open %s: %s\n", file_name, + "minishell: %s: failed to open %s: %s", file_name, strerror(errno)); } diff --git a/srcs/semantic_analysis/state_command.c b/srcs/semantic_analysis/state_command.c index eb7626c..221902a 100644 --- a/srcs/semantic_analysis/state_command.c +++ b/srcs/semantic_analysis/state_command.c @@ -65,6 +65,9 @@ t_semantic_analysis_state_return state_command( return (update_machine_state(current_token->token_type, semantic_machine)); } + if (*current_token->token_lexem == '\0' + && current_token->is_surrounded_by_quotes == false) + return (TOKEN_PROCESSED); add_argument_to_command_args(current_token->token_lexem, ¤t_command->command_args); semantic_machine->machine_state = STATE_COMMAND; diff --git a/srcs/semantic_analysis/state_heredoc.c b/srcs/semantic_analysis/state_heredoc.c index 89124a9..b3a5325 100644 --- a/srcs/semantic_analysis/state_heredoc.c +++ b/srcs/semantic_analysis/state_heredoc.c @@ -12,35 +12,55 @@ #include "minishell.h" -static bool is_delimiter(const char *delimiter, const char *line) +static char *process_data(char *heredoc_content, char *temp_line) { - const size_t delimiter_size = ft_strlen(delimiter); - const size_t line_size = ft_strlen(line); + ensure_stdin_is_open(); + if (g_received_signal == 130) + set_exit_status(130); + free(temp_line); + return (heredoc_content); +} - return (delimiter_size == line_size && ft_strcmp(line, delimiter) == 0); +static void update_heredoc_content(char **heredoc_content, char *temp_line, + char *new_line, int *heredoc_lines) +{ + ft_asprintf(&new_line, "%s%s\n", *heredoc_content, temp_line); + free(temp_line); + free(*heredoc_content); + *heredoc_content = new_line; + if (*heredoc_lines == 0) + *(heredoc_lines) += 2; + else + ++*(heredoc_lines); } static char *build_heredoc_content(const char *delimiter) { - char *new_line; - char *heredoc_content; - char *temp_line; + char *new_line; + char *heredoc_content; + char *temp_line; + int lines; + lines = 0; heredoc_content = ft_strdup(""); + new_line = NULL; while (HEREDOC_PROCESSING) { - temp_line = readline("captain'hirdock>"); - if (is_delimiter(delimiter, temp_line)) + if (g_received_signal == SIGINT) + break ; + temp_line = prompt_gets_user_input(SUBPROMPT); + if (g_received_signal == SIGINT) + break ; + if (temp_line == CTRL_D) { - free(temp_line); + heredoc_interruption_routine(delimiter, lines); break ; } - ft_asprintf(&new_line, "%s%s\n", heredoc_content, temp_line); - free(temp_line); - free(heredoc_content); - heredoc_content = new_line; + if (is_delimiter(delimiter, temp_line)) + break ; + update_heredoc_content(&heredoc_content, temp_line, new_line, &lines); } - return (heredoc_content); + return (process_data(heredoc_content, temp_line)); } static void save_heredoc_content(t_command *current_command, diff --git a/srcs/signals_handling/setup_command_mode_signals.c b/srcs/signals_handling/setup_command_mode_signals.c new file mode 100644 index 0000000..65f0367 --- /dev/null +++ b/srcs/signals_handling/setup_command_mode_signals.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* setup_command_mode_signals. :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/13 23:23:17 by tchobert #+# #+# */ +/* Updated: 2025/02/13 23:23:31 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void setup_command_mode_signals_handling(void) +{ + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGCONT, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGPIPE, SIG_DFL); +} diff --git a/srcs/signals_handling/setup_execution_mode_signals_handling.c b/srcs/signals_handling/setup_execution_mode_signals_handling.c new file mode 100644 index 0000000..612a158 --- /dev/null +++ b/srcs/signals_handling/setup_execution_mode_signals_handling.c @@ -0,0 +1,13 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* setup_execution_mode_signals_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/14 21:05:11 by tchobert #+# #+# */ +/* Updated: 2025/02/14 21:05:22 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" diff --git a/srcs/signals_handling/setup_heredoc_signals_handling.c b/srcs/signals_handling/setup_heredoc_signals_handling.c new file mode 100644 index 0000000..327b265 --- /dev/null +++ b/srcs/signals_handling/setup_heredoc_signals_handling.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* setup_heredoc_signals_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/14 15:53:56 by tchobert #+# #+# */ +/* Updated: 2025/02/14 15:54:12 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void simulate_eof(void) +{ + const int devnull = open("/dev/null", O_RDONLY); + + if (devnull != -1) + { + dup2(devnull, STDIN_FILENO); + close(devnull); + } +} + +static void sigint_for_heredoc(int signum) +{ + g_received_signal = signum; + write(STDOUT_FILENO, "\n", 1); + set_exit_status(128 + signum); + rl_replace_line("", 0); + rl_done = 1; + simulate_eof(); +} + +void setup_heredoc_signals_handling(void) +{ + signal(SIGINT, sigint_for_heredoc); + signal(SIGTERM, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGCONT, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGPIPE, SIG_IGN); +} diff --git a/srcs/signals_handling/setup_main_process_signals_handling.c b/srcs/signals_handling/setup_main_process_signals_handling.c new file mode 100644 index 0000000..a684607 --- /dev/null +++ b/srcs/signals_handling/setup_main_process_signals_handling.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* command_interpreter_signals_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tchobert +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/13 17:24:37 by tchobert #+# #+# */ +/* Updated: 2025/02/13 17:24:46 by tchobert ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void sigint_handler(int signum) +{ + (void)signum; + write(STDOUT_FILENO, "\n", 1); +} + +void setup_default_signals_handling(void) +{ + signal(SIGINT, sigint_handler); + signal(SIGTERM, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGCONT, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGPIPE, SIG_IGN); +} diff --git a/srcs/user_interface/signals.c b/srcs/signals_handling/signals.c similarity index 56% rename from srcs/user_interface/signals.c rename to srcs/signals_handling/signals.c index 63d9bc3..4e820aa 100644 --- a/srcs/user_interface/signals.c +++ b/srcs/signals_handling/signals.c @@ -12,36 +12,49 @@ #include "minishell.h" -static void init_signals(const struct sigaction *sa) -{ - if (sigaction(SIGINT, sa, NULL) == FAILURE) - { - perror("sigaction"); - exit(EXIT_FAILURE); - } - signal(SIGQUIT, SIG_IGN); -} +// static void init_signals(const struct sigaction *sa) +// { +// if (sigaction(SIGINT, sa, NULL) == FAILURE) +// { +// perror("sigaction"); +// exit(EXIT_FAILURE); +// } +// signal(SIGQUIT, SIG_IGN); +// } -void setup_signals(struct sigaction *sa) -{ - ft_memset(sa, 0, sizeof(struct sigaction)); - sa->sa_handler = signal_handler; - init_signals(sa); -} +// void setup_signals(struct sigaction *sa) +// { +// ft_memset(sa, 0, sizeof(struct sigaction)); +// sa->sa_handler = signal_handler; +// init_signals(sa); +// } -void sigint_routine(void) +static void sigint_routine(int signum) { + g_received_signal = signum; set_exit_status(128 + SIGINT); - printf("\n"); + write(STDIN_FILENO, "\n", 1); rl_on_new_line(); rl_replace_line("", 0); rl_redisplay(); } -void signal_handler(int signum) +void setup_main_prompt_signals_handling(void) { - if (signum == SIGINT) - { - sigint_routine(); - } + signal(SIGINT, sigint_routine); + signal(SIGTERM, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGCONT, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGPIPE, SIG_IGN); } + +// void signal_handler(int signum) +// { +// if (signum == SIGINT) +// { +// sigint_routine(); +// } +// } diff --git a/srcs/user_interface/prompt.c b/srcs/user_interface/prompt.c index c79e5e0..7267aa7 100644 --- a/srcs/user_interface/prompt.c +++ b/srcs/user_interface/prompt.c @@ -17,11 +17,21 @@ static void prompt_asks_next_history_entry(const char *user_input_line) add_user_input_line_to_history(user_input_line); } -char *prompt_gets_user_input(void) +char *prompt_gets_user_input(bool is_subprompt) { char *user_input_line; - user_input_line = readline(MSH_PROMPT); - prompt_asks_next_history_entry(user_input_line); + if (is_subprompt == false) + { + setup_main_prompt_signals_handling(); + user_input_line = readline(MSH_PROMPT); + prompt_asks_next_history_entry(user_input_line); + } + else + { + setup_heredoc_signals_handling(); + user_input_line = readline(HEREDOC_PROMPT); + } + setup_default_signals_handling(); return (user_input_line); }