From 18d430c5cbdf5be39f40bfb1302f362e9e75bf7e Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Fri, 26 Nov 2021 20:44:29 +0100 Subject: [PATCH] CO-CODE Hugo-Luke + last_exit_status set/get functions for here_doc + TODO : replace all occurences of last_exit_status + **environ fix + builtin_unset() fix --- Makefile | 1 + headers/minishell_prototypes.h | 8 +- srcs/builtins/unset.c | 18 ++- srcs/free.c | 4 +- srcs/generic.c | 2 + srcs/init.c | 14 +- srcs/last_exit_status.c | 37 +++++ srcs/main.c | 14 +- srcs/parsing/HUGO_WIP.c | 189 ----------------------- srcs/parsing/redirections/here_doc.c | 45 +++--- srcs/parsing/redirections/redirections.c | 9 +- tests/env_var_test.c | 17 ++ test_environ.c => tests/test_environ.c | 0 13 files changed, 119 insertions(+), 239 deletions(-) create mode 100644 srcs/last_exit_status.c delete mode 100644 srcs/parsing/HUGO_WIP.c create mode 100644 tests/env_var_test.c rename test_environ.c => tests/test_environ.c (100%) diff --git a/Makefile b/Makefile index bdedc6e..4657c2c 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ SRCS = main.c init.c free.c generic.c \ redirections.c here_doc.c \ exec_cmd_line.c pipeline.c \ find_access.c subshell_exec.c subshell_wait.c simple_cmd_builtin.c \ + last_exit_status.c \ cd.c pwd.c export.c unset.c exit.c env.c echo.c DIR_OBJS = builds diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 7823d42..15600bc 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/11/24 18:38:11 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 19:04:25 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,7 @@ int switch_heredoc_sigint; // Init -int init(t_all *c, char *envp[]); +int init(t_all *c); char **retrieve_path(char *envp[]); int set_terminal_attributes(struct termios *ori_termios, struct termios *interactive_termios, @@ -91,4 +91,8 @@ char *ft_strdup_quotes(const char *s); void sigint_handler_interactive(int signum); void sigint_handler_heredoc(int signum); +// last_exit_status +int set_last_exit_status(int new_value); +int get_last_exit_status(void); + #endif diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c index 2db1c14..4b81500 100644 --- a/srcs/builtins/unset.c +++ b/srcs/builtins/unset.c @@ -5,19 +5,21 @@ int builtin_unset(int argc, char *argv[], t_all *c) { extern char **environ; int env_position; + int i; (void)argc; (void)c; - env_position = getenv_position(environ, argv[1]); - if (environ[env_position] == '\0') - return (0); - while (environ[env_position + 1]) + i = 1; + while (argv[i]) { + env_position = getenv_position(environ, argv[i]); free(environ[env_position]); - environ[env_position] = ft_strdup(environ[env_position + 1]); - env_position++; + while (environ[env_position]) + { + environ[env_position] = environ[env_position + 1]; + env_position++; + } + i++; } - free(environ[env_position]); - environ[env_position] = NULL; return (0); } diff --git a/srcs/free.c b/srcs/free.c index ba0d477..8f223ff 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -14,10 +14,12 @@ int free_exit(t_all *c, int exit_status) { + extern char **environ; + free(c->prompt_base); free(c->prompt); ft_lstclear((t_list **)&c->token_list, free); -// ft_free_2d_arr(c->envp); + ft_free_2d_arr(environ); ft_free_2d_arr(c->path); free_pipeline(&c->cmd_arr); //if (c->termios_changed) diff --git a/srcs/generic.c b/srcs/generic.c index 002eec3..9375282 100644 --- a/srcs/generic.c +++ b/srcs/generic.c @@ -137,6 +137,8 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr) char **new_arr; new_arr = ft_calloc(ft_2d_arrlen(ptr) + add_nbr + 1, sizeof (void *)); + if (!new_arr) + return (NULL); arr = (char **)ptr; i = 0; while (arr[i]) diff --git a/srcs/init.c b/srcs/init.c index a5c9e6f..ba18d9d 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/11/25 23:59:33 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 19:02:24 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,16 +18,16 @@ static char *init_prompt_base(void); char *init_prompt(char *prompt_base); //int init(t_all *c, char *envp[]) -int init(t_all *c, char **environ) +int init(t_all *c) { - (void)environ; + extern char **environ; + g_all = c; ft_bzero(c, sizeof (*c)); -// c->envp = ft_dup_2d_arr(envp, (t_dup_f)ft_strdup); // TEST WIP -// if (!c->envp) -// return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); + environ = ft_dup_2d_arr(environ, (t_dup_f)ft_strdup); + if (!environ) + return (ft_reti_perror(0, "ft_dup_2d_char_arr(environ) error")); //print_matrix(c->envp, "\n --- \n"); // TEST WIP -// c->path = retrieve_path(c->envp); // No return check. Its intended. PATH is optional c->path = retrieve_path(environ); // No return check. Its intended. PATH is optional c->prompt_base = init_prompt_base(); if (!c->prompt_base) diff --git a/srcs/last_exit_status.c b/srcs/last_exit_status.c new file mode 100644 index 0000000..b3970c8 --- /dev/null +++ b/srcs/last_exit_status.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* last_exit_status.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/26 19:02:27 by lperrey #+# #+# */ +/* Updated: 2021/11/26 19:04:35 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int set_last_exit_status(int new_value) +{ + static int last_exit_status = 0; + + if (new_value >= 0) + last_exit_status = new_value; + return (last_exit_status); +} + +int get_last_exit_status(void) +{ + return (HUGO_set_last_exit_status(-1)); +} + +/* void ALT_set_last_exit_status(int new_value, int *set_last_exit_status_ptr) +{ + static int *last_exit_status_ptr = NULL; + + if (set_last_exit_status_ptr) + last_exit_status_ptr = set_last_exit_status_ptr; + else if (new_value >= 0) + *last_exit_status_ptr = new_value; +} */ diff --git a/srcs/main.c b/srcs/main.c index 67f752c..d7d8f15 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/25 19:48:07 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 20:33:54 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,17 +16,15 @@ int main(int argc, char *argv[]) { t_all c; - extern char **environ; (void)argc; (void)argv; -// if (!init(&c, envp)) - if (!init(&c, environ)) + if (!init(&c)) free_exit(&c, EXIT_FAILURE); //putenv("VAR=W1 W2 W3"); // TEMP TEST - //if (isatty(STDIN_FILENO)) - shell_loop(&c); - //else - // shell_script(&c); +// if (argv[1] || !isatty(STDIN_FILENO)) +// shell_script(&c); +// else + shell_loop(&c); return (0); } diff --git a/srcs/parsing/HUGO_WIP.c b/srcs/parsing/HUGO_WIP.c deleted file mode 100644 index 9865c25..0000000 --- a/srcs/parsing/HUGO_WIP.c +++ /dev/null @@ -1,189 +0,0 @@ - -#include "minishell.h" - -int is_redirection(enum e_token_id id) -{ - if (id == T_LESS) // < - return (1); - else if (id == T_GREAT) // > - return (1); - else if (id == T_DLESS) // << - return (1); - else if (id == T_DGREAT) // >> - return (1); - else - return (0); -} - -// count nbr word in cmd, minus redirection and heredoc -int next_cmd(t_token *token) -{ - int i; - - i = 0; - while (token && token->id != T_PIPE) - { - if (is_redirection(token->id)) - i--; - else - i++; - token = token->next; - } - if (token && token->id == T_PIPE) - token = token->next; - return (i); -} - -void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr) -{ - int argc; - int j; - int i; - int redirection; - - i = 0; - while (cmd_nbr) - { - argc = next_cmd(token); - cmd[i]->argv = calloc(argc + 1, sizeof(char *)); - cmd[i]->argv[argc] = NULL; - j = 0; - redirection = is_redirection(token->id); - while (token && token->id != T_PIPE) - { - if (!redirection && token->id == T_WORD) - { - cmd[i]->argv[j] = ft_strdup(token->content); - j++; - } - redirection = is_redirection(token->id); - token = token->next; - } - if (token && token->id == T_PIPE) - token = token->next; - cmd_nbr--; - i++; - } -} - -int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) -{ - cmd->builtin_command = &builtin; - return (1); -} - -int handle_builtin(t_cmd *cmd) -{ // Il faut penser à comparer un char de plus (\0 inclus) - if (!ft_strncmp(cmd->argv[0], "echo", 4)) - return (fill_builtin(cmd, &builtin_echo)); -// else if (!ft_strncmp(cmd->argv[0], "cd", 2)) -// return (fill_builtin(cmd, &builtin_cd)); -// else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) -// return (fill_builtin(cmd, &builtin_pwd)); -// else if (!ft_strncmp(cmd->argv[0], "export", 6)) -// return (fill_builtin(cmd, &builtin_export)); -// else if (!ft_strncmp(cmd->argv[0], "unset", 5)) -// return (fill_builtin(cmd, &builtin_unset)); - else if (!ft_strncmp(cmd->argv[0], "env", 3)) - return (fill_builtin(cmd, &builtin_env)); - else if (!ft_strncmp(cmd->argv[0], "exit", 4)) - return (fill_builtin(cmd, &builtin_exit)); - return (0); -} - -void find_path(char **argv, char **envp) -{ - int i; - char **path; - char *cmd; - - i = 0; - while (envp[i] && ft_strncmp(envp[i], "PATH=", 5)) - i++; - path = ft_split(envp[i] + 5, ':'); // 5 = lentgh of "PATH=" - i = -1; - while (*path && i != 0) - { - cmd = ft_strjoin(path[0], "/"); - cmd = ft_strjoin(cmd, argv[0]); - i = access(cmd, X_OK); - path++; - } - if (!(*path)) - exit(0); // gerer erreur - argv[0] = cmd; -} - -void handle_path(t_cmd **cmd_arr, char **envp) -{ - int i; - - i = 0; - while (cmd_arr[i]) - { - if (!handle_builtin(cmd_arr[i])) - find_path(cmd_arr[i]->argv, envp); - i++; - } -} - -void fd_redirection(t_token *token, t_cmd *cmd) -{ - int flag; - - if (token->id == T_LESS) // '<' - { - flag = O_RDONLY | O_CREAT; // O_CREAT ? Pourquoi donc ? - if (cmd->fd_in != 0) - close(cmd->fd_in); - cmd->fd_in = open(token->next->content, flag); - } - else if (token->id == T_GREAT) // '>' - { - flag = O_WRONLY | O_CREAT | O_TRUNC; - cmd->fd_out = open(token->next->content, flag, S_IRWXU); - } - else if (token->id == T_DGREAT) // '>>' - { - flag = O_WRONLY | O_CREAT | O_APPEND; - cmd->fd_out = open(token->next->content, flag, S_IRWXU); - } -} - -void fd_heredoc(t_token *token, t_cmd *cmd) -{ - (void)token; - (void)cmd; -} - -void handle_fd(t_token *token, t_cmd **cmd_arr) -{ - int *pipes_fd; - int i; - - i = 0; - while (cmd_arr[i]) - { - cmd_arr[i]->fd_out = 1; - while (token && token->id != T_PIPE) - { - if (token->id == T_DGREAT) // '<<' - fd_heredoc(token, cmd_arr[i]); - else - fd_redirection(token, cmd_arr[i]); - token = token->next; - } - if (token && token->id == T_PIPE) - { - token = token->next; - pipes_fd = calloc(2, sizeof(int)); - pipe(pipes_fd); - if (cmd_arr[i]->fd_out == 1) - cmd_arr[i]->fd_out = pipes_fd[1]; - else - close(pipes_fd[1]); - cmd_arr[i + 1]->fd_in = pipes_fd[0]; - } - i++; - } -} diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c index 1a551a7..f0d292a 100644 --- a/srcs/parsing/redirections/here_doc.c +++ b/srcs/parsing/redirections/here_doc.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ -/* Updated: 2021/11/25 22:21:16 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 20:00:25 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,23 +29,24 @@ int here_doc(char *delimiter) // Peut-être remplacer gnl() par readline() pour avoir une gestion correct // du terminal (actuellement l'affichage lors du changement de ligne est foireux). int here_doc; + int ret; - here_doc = open(TMP_HERE_DOC, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); - if (here_doc == -1) - return (ft_reti_perror_io(-1, "open() ", TMP_HERE_DOC)); delimiter = ft_strdup_quotes(delimiter); if (!delimiter) return (ft_reti_perror(-1, "ft_strdup_quotes()")); - if (!here_doc_write(delimiter, here_doc)) - { - free(delimiter); - if (unlink(TMP_HERE_DOC) == -1) - return (ft_reti_perror_io(-1, "unlink() ", TMP_HERE_DOC)); - return (-1); - } + here_doc = open(TMP_HERE_DOC, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (here_doc == -1) + return (ft_reti_perror_io(-1, "open() ", TMP_HERE_DOC)); + ret = here_doc_write(delimiter, here_doc); free(delimiter); if (close(here_doc) == -1) ft_perror_io("close() ", TMP_HERE_DOC); + if (ret != 0) + { + if (unlink(TMP_HERE_DOC) == -1) + return (ft_reti_perror_io(ret, "unlink() ", TMP_HERE_DOC)); + return (ret); + } here_doc = open(TMP_HERE_DOC, O_RDONLY); if (here_doc == -1) ft_perror_io("open() ", TMP_HERE_DOC); @@ -77,13 +78,14 @@ static int here_doc_write(char *delimiter, int doc_fd) { char *line; size_t line_count; - struct sigaction signal_action; + struct sigaction signal_action; + ft_bzero(&signal_action, sizeof(signal_action)); signal_action.sa_handler = sigint_handler_heredoc; sigaction(SIGINT, &signal_action, NULL); switch_heredoc_sigint = 0; - //rl_event_hook = void_func_return_readline; - rl_signal_event_hook = void_func_return_readline; + rl_event_hook = void_func_return_readline; + //rl_signal_event_hook = void_func_return_readline; line_count = 0; while (1) { @@ -91,10 +93,7 @@ static int here_doc_write(char *delimiter, int doc_fd) line = NULL; line = readline("> "); if (switch_heredoc_sigint == 1) - { - // todo : gerer le statut exit 130 - return (1); - } + return (set_last_exit_status(128 + SIGINT)); // TODO Macro for error if (!line) { // TODO : error print wrapper ft_putstr_fd("minishell: ", 2); @@ -103,18 +102,20 @@ static int here_doc_write(char *delimiter, int doc_fd) ft_putstr_fd(" delimited by end-of-file (wanted `", 2); ft_putstr_fd(delimiter, 2); ft_putstr_fd("')\n", 2); - return (1); + return (-1); } if (ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0) // Ou ft_strlen(delimiter) + 1 ? Ça devrais être identique et ça peux se calculer une seul fois. break ; if (write(doc_fd, line, ft_strlen(line)) == -1) - return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + return (ft_reti_perror_free(-1, line, free, "write() "TMP_HERE_DOC)); if (write(doc_fd, "\n", 1) == -1) - return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + return (ft_reti_perror_free(-1, line, free, "write() "TMP_HERE_DOC)); free(line); } free(line); - return (1); + signal_action.sa_handler = SIG_IGN; + sigaction(SIGINT, &signal_action, NULL); + return (0); } /* diff --git a/srcs/parsing/redirections/redirections.c b/srcs/parsing/redirections/redirections.c index a8bcc55..185d32f 100644 --- a/srcs/parsing/redirections/redirections.c +++ b/srcs/parsing/redirections/redirections.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ -/* Updated: 2021/11/18 22:17:44 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 20:00:42 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -67,7 +67,12 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) { cmd->fd_in = here_doc(t->next->content); if (cmd->fd_in == -1) - return (ft_reti_print(0, "minishell: heredoc error\n", 2)); + { + ft_putstr_fd("minishell: heredoc error\n", 2); + cmd->error = 42; // WIP error status + } + else if (cmd->fd_in > 128) // TODO Macro + return (0); } return (1); } diff --git a/tests/env_var_test.c b/tests/env_var_test.c new file mode 100644 index 0000000..6c15b4f --- /dev/null +++ b/tests/env_var_test.c @@ -0,0 +1,17 @@ + +# include +# include + +int main(int argc, char *argv[], char *envp[]) +{ + int i; + + printf("argc = %i\n", argc); + i = 0; + while (argv[i]) + { + printf("%s = |%s|\n", argv[i], getenv(argv[i])); + i++; + } + return (0); +} diff --git a/test_environ.c b/tests/test_environ.c similarity index 100% rename from test_environ.c rename to tests/test_environ.c