diff --git a/Makefile b/Makefile index 9a2a361..0a3a5b0 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,14 @@ CC = clang CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) -DIR_SRCS = srcs srcs/builtins \ +DIR_SRCS = srcs \ + srcs/builtins \ srcs/lexing \ srcs/parsing srcs/parsing/valid_syntax \ srcs/parsing/expansions srcs/parsing/redirections \ - srcs/exec + srcs/exec \ + srcs/generic \ + srcs/misc \ INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) @@ -25,19 +28,21 @@ LIBS = -L $(LIBFT_D) -lft \ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a -SRCS = main.c init.c retrieve_path.c free.c generic.c error_wrappers.c \ - signals.c \ +SRCS = main.c \ shell_loop.c shell_script.c \ + init.c retrieve_path.c free.c \ + signals.c error_wrappers.c last_exit_status.c \ lexing.c fill_token.c check_operators.c \ parsing.c create_pipeline.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ - words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ - ft_split_quotes.c ft_strdup_quotes.c \ + expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.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 + cd.c pwd.c export.c unset.c exit.c env.c echo.c \ + ft_split_quotes.c ft_strdup_quotes.c \ + ft_strjoinfree.c ft_lst_func.c ft_isinset_str.c ft_is_posix_name.c \ + ft_getenv.c ft_free_null.c ft_2d_arr_func.c \ DIR_OBJS = builds OBJS = $(SRCS:%.c=$(DIR_OBJS)/%.o) diff --git a/README.md b/README.md index e2fef2e..a8b3bd1 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,8 @@ two more functions : ## ressources : - [termcap](https://www.gnu.org/software/termutils/manual/termcap-1.3/html_chapter/termcap_toc.html) -- [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) / [second source](https://tiswww.case.edu/php/chet/readline/README) +- [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) +- [readline](https://tiswww.case.edu/php/chet/readline/README) - [transformer arbre normal en arbre binaire](https://fr.wikipedia.org/wiki/Arbre_binaire#Transformation_d'un_arbre_quelconque_en_un_arbre_binaire) - [send EOF to process](https://unix.stackexchange.com/questions/493578/how-to-send-d-eot-character-to-stdin-of-a-shell-process) - [get root access 1](https://vitux.com/how-to-become-root-user-in-ubuntu-command-line-using-su-and-sudo/) diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index c1b39f3..60bb6c6 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/12/10 10:29:18 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:56:21 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,9 +20,6 @@ extern char **environ; int init(t_all *c); char *init_prompt(char *prompt_base); char **retrieve_path(void); -int set_terminal_attributes(struct termios *ori_termios, - struct termios *interactive_termios, - int *termios_changed); // WIP, TEST, TEMP, PLACEHOLDER, NOT IMPORTANT, :) void set_signals_behaviour(void); // Shell modes @@ -40,8 +37,8 @@ int valid_command_separator(const t_token *token_list); size_t count_pipes(t_token *token_list); t_cmd **pipeline_alloc(size_t cmd_nbr); int pipeline_fill_argv(t_token *token_list, t_cmd **pipeline); -int words_expansions(t_token *token_list); -int token_expansions(t_token **t); +int expansions(t_token *token_list, t_cmd **pipeline); +int token_expansions(t_token *t); int redirections(t_token *token_list, t_cmd **pipeline); // Exec @@ -72,6 +69,7 @@ typedef void (*t_free_f)(void *); // generic // Error wrappers int shell_error(char *s1, char *s2, char *s3, int ret_val); int shell_perror(char *s1, char *s2, char *s3, int ret_val); +int ft_reti_perror_io(int ret, char *err_str, char *io_file); // Generic char *ft_strjoinfree(char *s1, char *s2); @@ -82,13 +80,10 @@ int ft_isinset_str(char *str, char *set); size_t ft_2d_arrlen(void *ptr); // Replace ft_arrlen() char **ft_dup_2d_char_arr(char **ptr); void *ft_resize_2d_arr(void *ptr, size_t add_nbr); -void print_matrix(char **matrix, char *sep); t_list *ft_lstbeforelast(t_list *lst); void *ft_lstnew_generic(size_t lst_size, size_t content_size); typedef void *(*t_dup_f)(void *); void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)); -void ft_perror_io(char *err_str, char *io_file); -int ft_reti_perror_io(int ret, char *err_str, char *io_file); void ft_free_null(void *ptr); char *ft_getenv(char *env_var); size_t ft_getenv_position(char *env_var); @@ -97,7 +92,7 @@ int ft_is_posix_name(char *str); char **ft_split_quotes(char const *s, char c); char *ft_strdup_quotes(const char *s); -// signals.c +// Signals handler void sigint_handler_interactive(int signum); void sigint_handler_heredoc(int signum); diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 69b5f79..8fe4e6b 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ +/* Updated: 2021/12/16 06:34:29 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,11 +42,6 @@ typedef struct s_all char *prompt_base; char *prompt; t_token *token_list; -// struct termios ori_termios; -// struct termios interactive_termios; -// int termios_changed; -// struct sigaction ori_signal_behaviour; -// struct sigaction signal_behaviour; } t_all; #endif diff --git a/minishell_tests b/minishell_tests index 3c89304..71beb2e 160000 --- a/minishell_tests +++ b/minishell_tests @@ -1 +1 @@ -Subproject commit 3c89304cdad9b8622ee43a86249a34c94f3f2988 +Subproject commit 71beb2eeb7d0584f28bc9265e28e9814751c967f diff --git a/srcs/debug.c b/srcs/debug.c new file mode 100644 index 0000000..d3dd7e5 --- /dev/null +++ b/srcs/debug.c @@ -0,0 +1,35 @@ + +#include "minishell.h" + +// pour imprimer une char ** en precisant comment separer les char * +void print_matrix(char **matrix, char *sep) +{ + int i; + + i = 0; + while (matrix[i]) + { + printf("%s", matrix[i]); + if (matrix[i + 1]) + printf("%s", sep); + //fflush(stdout); + i++; + } + write(1, "\n", 1); +} + +void print_pipeline(t_cmd **pipeline) +{ + int i; + + i = 0; + while (pipeline[i]) + { + printf("CMD %i, fd_in=%i, fd_out=%i\n", i, pipeline[i]->fd_in, pipeline[i]->fd_out); + ft_putstr_fd(" |", 1); + print_matrix(pipeline[i]->argv, "|\n |"); + i++; + if (pipeline[i]) + ft_putstr_fd("----------------\n", 1); + } +} diff --git a/srcs/exec/find_access.c b/srcs/exec/find_access.c index 22d44a1..13e1b2b 100644 --- a/srcs/exec/find_access.c +++ b/srcs/exec/find_access.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/12/05 16:20:55 by lperrey ### ########.fr */ +/* Updated: 2021/12/16 05:57:42 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -103,10 +103,11 @@ static int handle_access_error(char *file_name) int tmp; tmp = errno; - ft_perror_io("minishell: ", file_name); + shell_perror(file_name, ": ", "", 0); errno = tmp; if (errno == EACCES) + return (EXIT_CMD_NOT_EXE); + else if (errno == ENOENT) return (EXIT_CMD_NOT_FOUND); return (1); - // 126 / EXIT_CMD_NOT_EXE } diff --git a/srcs/exec/pipeline.c b/srcs/exec/pipeline.c index 3a0354f..e8d61d2 100644 --- a/srcs/exec/pipeline.c +++ b/srcs/exec/pipeline.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ +/* Updated: 2021/12/11 05:24:07 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,14 +18,25 @@ static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c); int pipeline(t_all *c) { - if (!open_pipes(c->pipeline)) + t_cmd **pipeline; + int ret; + + pipeline = c->pipeline; + if (!open_pipes(pipeline)) return (0); - if (!pipeline_find_access(c->pipeline, c->path)) + if (!pipeline_find_access(pipeline, c->path)) return (0); - if (ft_2d_arrlen(c->pipeline) == 1 && c->pipeline[0]->builtin_f) - simple_command_builtin(c->pipeline[0], c); + if (pipeline[0]->builtin_f && ft_2d_arrlen(pipeline) == 1) + { + if (!pipeline[0]->error) + { + ret = simple_command_builtin(pipeline[0], c); + if (ret != EXIT_SUCCESS) + set_last_exit_status(ret); + } + } else - wait_subshell(pipeline_exec(c->pipeline, c)); + wait_subshell(pipeline_exec(pipeline, c)); free_pipeline(&c->pipeline); return (1); } @@ -62,8 +73,11 @@ static int pipeline_find_access(t_cmd *pipeline[], char *path[]) i = 0; while (pipeline[i]) { - if (!cmd_find_access(pipeline[i], path)) - return (0); + if (!pipeline[i]->error) + { + if (!cmd_find_access(pipeline[i], path)) + return (0); + } i++; } return (1); diff --git a/srcs/generic.c b/srcs/generic.c deleted file mode 100644 index 15ef502..0000000 --- a/srcs/generic.c +++ /dev/null @@ -1,293 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* generic.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: lperrey +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ -/* Updated: 2021/12/10 10:28:48 by hulamy ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -char *ft_strjoinfree(char *s1, char *s2) -{ - char *str; - - str = ft_strjoin(s1, s2); - free(s1); - free(s2); - return (str); -} - -char *ft_strjoinfree_s1(char *s1, const char *s2) -{ - char *str; - - str = ft_strjoin(s1, s2); - free(s1); - return (str); -} - -char *ft_strjoinfree_s2(const char *s1, char *s2) -{ - char *str; - - str = ft_strjoin(s1, s2); - free(s2); - return (str); -} - -void ft_lstprint(t_list *lst, int fd) -{ - while (lst) - { - ft_putendl_fd(lst->content, fd); - lst = lst->next; - } -} - -int ft_isinset_str(char *str, char *set) -{ - size_t i; - size_t i_set; - int valid; - - i = 0; - while (str[i]) - { - valid = 0; - i_set = 0; - while (set[i_set] && !valid) - { - if (str[i] == set[i_set]) - valid = 1; - i_set++; - } - if (!valid) - return (0); - i++; - } - return (i); -} - -size_t ft_2d_arrlen(void *ptr) // Replace ft_arrlen() -{ - size_t len; - char **arr; - - arr = (char **)ptr; - len = 0; - while (arr[len] != NULL) - len++; - return (len); -} -/* -char **ft_dup_2d_char_arr(char **ptr) // Superflu si ft_dup_2d_arr() fonctionne -{ - unsigned int i; - char **arr; - char **new_arr; - - new_arr = malloc((ft_2d_arrlen(ptr) + 1) * sizeof (void *)); - if (!new_arr) - return (NULL); - arr = (char **)ptr; - i = 0; - while (arr[i]) - { - new_arr[i] = ft_strdup(arr[i]); - if (!new_arr[i]) - return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); - i++; - } - new_arr[i] = NULL; - return (new_arr); -} */ - -// Test generic. Pas certain que ça fonctionne bien avec le pointeur sur fonction -void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) -{ - unsigned int i; - char **arr; - char **new_arr; - - new_arr = ft_calloc(ft_2d_arrlen(ptr) + 1, sizeof (void *)); - if (!new_arr) - return (NULL); - arr = (char **)ptr; - i = 0; - while (arr[i]) - { - new_arr[i] = dup_func(arr[i]); - if (!new_arr[i]) - return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); - i++; - } - return (new_arr); -} - -void *ft_resize_2d_arr(void *ptr, size_t add_nbr) -{ - unsigned int i; - char **arr; - 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]) - { - new_arr[i] = arr[i]; - i++; - } - free(arr); - return (new_arr); -} - -// pour imprimer une char ** en precisant comment separer les char * -void print_matrix(char **matrix, char *sep) -{ - int i; - - i = 0; - while (matrix[i]) - { - printf("%s", matrix[i]); - if (matrix[i + 1]) - printf("%s", sep); - fflush(stdout); - i++; - } - write(1, "\n", 1); -} - -t_list *ft_lstbeforelast(t_list *lst) -{ - if (!lst || !lst->next) - return (NULL); - while (lst->next->next) - lst = lst->next; - return (lst); -} - -/* if "content_size == 0", return lst with "lst->content == NULL" */ -void *ft_lstnew_generic(size_t lst_size, size_t content_size) -{ - t_list *elem; - void *content; - - if (content_size == 0) - content = NULL; - else - { - content = ft_calloc(content_size, 1); - if (!content) - return (NULL); - } - elem = ft_calloc(1, lst_size); - if (!elem) - { - free(content); - return (NULL); - } - elem->content = content; - elem->next = NULL; - return (elem); -} - -void ft_perror_io(char *err_str, char *io_file) -{ - ft_putstr_fd(err_str, 2); - perror(io_file); -} - -int ft_reti_perror_io(int ret, char *err_str, char *io_file) -{ - ft_putstr_fd(err_str, 2); - perror(io_file); - return (ret); -} - -void ft_free_null(void *ptr) -{ - free(*(char**)ptr); - *(char**)ptr = NULL; -} - -/* -** Search for an environement variable, -** and return a pointer to the first character after "env_var=" . -** Return NULL if env_var not found. -*/ -char *ft_getenv(char *env_var) -{ - int i; - char *tmp; - size_t env_var_len; - - env_var_len = ft_strlen(env_var); - i = 0; - tmp = NULL; - while (!tmp && environ[i]) - { - if (environ[i][env_var_len] == '=') - { - if (ft_strncmp(environ[i], env_var, env_var_len) == 0) - tmp = &environ[i][env_var_len + 1]; - else - i++; - } - else - i++; - } - return (tmp); -} - -/* -** Like ft_getenv(), but return position of env_var instead of value. -** If env_var not found, return last position of **environ (== NULL) -*/ -size_t ft_getenv_position(char *env_var) -{ - int i; - int found; - size_t env_var_len; - - env_var_len = ft_strlen(env_var); - i = 0; - found = 0; - while (!found && environ[i]) - { - if (environ[i][env_var_len] == '=') - { - if (ft_strncmp(environ[i], env_var, env_var_len) == 0) - found = 1; - else - i++; - } - else - i++; - } - return (i); -} - -int ft_is_posix_name(char *str) -{ - unsigned int i; - - if (str[0] != '_' && !ft_isalpha(str[0])) - return (0); - i = 1; - while (str[i]) - { - if (str[i] != '_' && !ft_isalnum(str[i])) - return (0); - i++; - } - return (i); -} diff --git a/srcs/generic/ft_2d_arr_func.c b/srcs/generic/ft_2d_arr_func.c new file mode 100644 index 0000000..39b763e --- /dev/null +++ b/srcs/generic/ft_2d_arr_func.c @@ -0,0 +1,67 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_2d_arr_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:43:33 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +// Replace ft_arrlen() +size_t ft_2d_arrlen(void *ptr) +{ + size_t len; + char **arr; + + arr = (char **)ptr; + len = 0; + while (arr[len] != NULL) + len++; + return (len); +} + +void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) +{ + unsigned int i; + char **arr; + char **new_arr; + + new_arr = ft_calloc(ft_2d_arrlen(ptr) + 1, sizeof (void *)); + if (!new_arr) + return (NULL); + arr = (char **)ptr; + i = 0; + while (arr[i]) + { + new_arr[i] = dup_func(arr[i]); + if (!new_arr[i]) + return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); + i++; + } + return (new_arr); +} + +void *ft_resize_2d_arr(void *ptr, size_t add_nbr) +{ + unsigned int i; + char **arr; + 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]) + { + new_arr[i] = arr[i]; + i++; + } + free(arr); + return (new_arr); +} diff --git a/srcs/generic/ft_free_null.c b/srcs/generic/ft_free_null.c new file mode 100644 index 0000000..1c87157 --- /dev/null +++ b/srcs/generic/ft_free_null.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_free_null.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:59:21 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_free_null(void *ptr) +{ + free(*(char **)ptr); + *(char **)ptr = NULL; +} diff --git a/srcs/generic/ft_getenv.c b/srcs/generic/ft_getenv.c new file mode 100644 index 0000000..c3c2475 --- /dev/null +++ b/srcs/generic/ft_getenv.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_getenv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:44:06 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +/* +** Search for an environement variable, +** and return a pointer to the first character after "env_var=" . +** Return NULL if env_var not found. +*/ +char *ft_getenv(char *env_var) +{ + int i; + char *tmp; + size_t env_var_len; + + env_var_len = ft_strlen(env_var); + i = 0; + tmp = NULL; + while (!tmp && environ[i]) + { + if (environ[i][env_var_len] == '=') + { + if (ft_strncmp(environ[i], env_var, env_var_len) == 0) + tmp = &environ[i][env_var_len + 1]; + else + i++; + } + else + i++; + } + return (tmp); +} + +/* +** Like ft_getenv(), but return position of env_var instead of value. +** If env_var not found, return last position of **environ (== NULL) +*/ +size_t ft_getenv_position(char *env_var) +{ + int i; + int found; + size_t env_var_len; + + env_var_len = ft_strlen(env_var); + i = 0; + found = 0; + while (!found && environ[i]) + { + if (environ[i][env_var_len] == '=') + { + if (ft_strncmp(environ[i], env_var, env_var_len) == 0) + found = 1; + else + i++; + } + else + i++; + } + return (i); +} diff --git a/srcs/generic/ft_is_posix_name.c b/srcs/generic/ft_is_posix_name.c new file mode 100644 index 0000000..20d9df4 --- /dev/null +++ b/srcs/generic/ft_is_posix_name.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_is_posix_name.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:50:43 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_is_posix_name(char *str) +{ + unsigned int i; + + if (str[0] != '_' && !ft_isalpha(str[0])) + return (0); + i = 1; + while (str[i]) + { + if (str[i] != '_' && !ft_isalnum(str[i])) + return (0); + i++; + } + return (i); +} diff --git a/srcs/generic/ft_isinset_str.c b/srcs/generic/ft_isinset_str.c new file mode 100644 index 0000000..d16823f --- /dev/null +++ b/srcs/generic/ft_isinset_str.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isinset_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:45:50 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_isinset_str(char *str, char *set) +{ + size_t i; + size_t i_set; + int valid; + + i = 0; + while (str[i]) + { + valid = 0; + i_set = 0; + while (set[i_set] && !valid) + { + if (str[i] == set[i_set]) + valid = 1; + i_set++; + } + if (!valid) + return (0); + i++; + } + return (i); +} diff --git a/srcs/generic/ft_lst_func.c b/srcs/generic/ft_lst_func.c new file mode 100644 index 0000000..5835388 --- /dev/null +++ b/srcs/generic/ft_lst_func.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:45:39 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_lstprint(t_list *lst, int fd) +{ + while (lst) + { + ft_putendl_fd(lst->content, fd); + lst = lst->next; + } +} + +t_list *ft_lstbeforelast(t_list *lst) +{ + if (!lst || !lst->next) + return (NULL); + while (lst->next->next) + lst = lst->next; + return (lst); +} + +/* if "content_size == 0", return lst with "lst->content == NULL" */ +void *ft_lstnew_generic(size_t lst_size, size_t content_size) +{ + t_list *elem; + void *content; + + if (content_size == 0) + content = NULL; + else + { + content = ft_calloc(content_size, 1); + if (!content) + return (NULL); + } + elem = ft_calloc(1, lst_size); + if (!elem) + { + free(content); + return (NULL); + } + elem->content = content; + elem->next = NULL; + return (elem); +} diff --git a/srcs/parsing/expansions/ft_split_MODIF.c b/srcs/generic/ft_split_MODIF.c similarity index 100% rename from srcs/parsing/expansions/ft_split_MODIF.c rename to srcs/generic/ft_split_MODIF.c diff --git a/srcs/parsing/expansions/ft_split_quotes.c b/srcs/generic/ft_split_quotes.c similarity index 100% rename from srcs/parsing/expansions/ft_split_quotes.c rename to srcs/generic/ft_split_quotes.c diff --git a/srcs/parsing/expansions/ft_strdup_quotes.c b/srcs/generic/ft_strdup_quotes.c similarity index 100% rename from srcs/parsing/expansions/ft_strdup_quotes.c rename to srcs/generic/ft_strdup_quotes.c diff --git a/srcs/generic/ft_strjoinfree.c b/srcs/generic/ft_strjoinfree.c new file mode 100644 index 0000000..44f5ab1 --- /dev/null +++ b/srcs/generic/ft_strjoinfree.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strjoinfree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ +/* Updated: 2021/12/16 03:39:09 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_strjoinfree(char *s1, char *s2) +{ + char *str; + + str = ft_strjoin(s1, s2); + free(s1); + free(s2); + return (str); +} + +char *ft_strjoinfree_s1(char *s1, const char *s2) +{ + char *str; + + str = ft_strjoin(s1, s2); + free(s1); + return (str); +} + +char *ft_strjoinfree_s2(const char *s1, char *s2) +{ + char *str; + + str = ft_strjoin(s1, s2); + free(s2); + return (str); +} diff --git a/srcs/error_wrappers.c b/srcs/misc/error_wrappers.c similarity index 88% rename from srcs/error_wrappers.c rename to srcs/misc/error_wrappers.c index aef5775..7871e30 100644 --- a/srcs/error_wrappers.c +++ b/srcs/misc/error_wrappers.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/12/01 17:16:30 by lperrey #+# #+# */ -/* Updated: 2021/12/05 16:26:48 by lperrey ### ########.fr */ +/* Updated: 2021/12/16 04:38:05 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,3 +43,10 @@ int shell_perror(char *s1, char *s2, char *s3, int ret_val) perror(NULL); return (ret_val); } + +int ft_reti_perror_io(int ret, char *err_str, char *io_file) +{ + ft_putstr_fd(err_str, STDERR_FILENO); + perror(io_file); + return (ret); +} diff --git a/srcs/free.c b/srcs/misc/free.c similarity index 93% rename from srcs/free.c rename to srcs/misc/free.c index 303a182..0e8c95b 100644 --- a/srcs/free.c +++ b/srcs/misc/free.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */ -/* Updated: 2021/12/02 00:42:33 by lperrey ### ########.fr */ +/* Updated: 2021/12/16 06:35:03 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,8 +20,6 @@ int exit_free(t_all *c, int exit_status) ft_free_2d_arr(environ); ft_free_2d_arr(c->path); free_pipeline(&c->pipeline); - //if (c->termios_changed) - // tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); rl_clear_history(); close_stdio(); exit(exit_status); diff --git a/srcs/init.c b/srcs/misc/init.c similarity index 100% rename from srcs/init.c rename to srcs/misc/init.c diff --git a/srcs/last_exit_status.c b/srcs/misc/last_exit_status.c similarity index 100% rename from srcs/last_exit_status.c rename to srcs/misc/last_exit_status.c diff --git a/srcs/retrieve_path.c b/srcs/misc/retrieve_path.c similarity index 100% rename from srcs/retrieve_path.c rename to srcs/misc/retrieve_path.c diff --git a/srcs/signals.c b/srcs/misc/signals.c similarity index 95% rename from srcs/signals.c rename to srcs/misc/signals.c index e21e689..77fd83d 100644 --- a/srcs/signals.c +++ b/srcs/misc/signals.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ -/* Updated: 2021/11/26 21:45:22 by lperrey ### ########.fr */ +/* Updated: 2021/12/16 15:06:50 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c index ae3e8ba..2324826 100644 --- a/srcs/parsing/expansions/expand_token.c +++ b/srcs/parsing/expansions/expand_token.c @@ -6,100 +6,125 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/10 10:27:50 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:51:33 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static t_list *ret_parameter_expansion(char *content, int *i); +static t_list *content_copy(char *content, int *i, int *quotes_state); +static t_list *content_expand(char *content, int *i); +static char *env_var_expansion(char *content, int *i); t_list *expand_token(char *content) { - int in_quotes; + int quotes_state; int i; - int i_exp; t_list head; t_list *expand; - in_quotes = 0; - i = 0; head.next = NULL; expand = &head; + quotes_state = 0; + i = 0; while (content[i]) { if (content[i] == '$') - { - expand->next = ret_parameter_expansion(content, &i); - expand = expand->next; - if (!expand) - {//todo wrap - perror("expand_token() error"); - return (ft_lstclear(&head.next, free)); - } - } + expand->next = content_expand(content, &i); else - { - expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&content[i]) + 1); - expand = expand->next; - i_exp = 0; - if (!expand) - {//todo wrap - perror("expand_token() error"); - return (ft_lstclear(&head.next, free)); - } - while (content[i] && (content[i] != '$' || in_quotes == IN_QUOTES)) - { - // quoting - if (content[i] == '\'' && in_quotes != IN_DQUOTES) - { - if (in_quotes == IN_QUOTES) - in_quotes = 0; - else - in_quotes = IN_QUOTES; - } - ((char *)expand->content)[i_exp++] = content[i++]; - } + expand->next = content_copy(content, &i, "es_state); + expand = expand->next; + if (!expand) + {//todo wrap + perror("expand_token() error"); + return (ft_lstclear(&head.next, free)); } } return (head.next); } -// a voir si je retourne pas plutot un "char *". -// Malloc la lst dans la fonction est peut-être un peu superflu et pas super clair. -static t_list *ret_parameter_expansion(char *content, int *i) +static t_list *content_copy(char *content, int *i, int *quotes_state) +{ + int i_exp; + t_list *expand; + + expand = ft_lstnew_generic(sizeof(t_list), ft_strlen(&content[*i]) + 1); + if (!expand) + return (NULL); + i_exp = 0; + while (content[*i] && (content[*i] != '$' || *quotes_state == IN_QUOTES)) + { + if (content[*i] == '\'' && *quotes_state != IN_DQUOTES) + { + if (*quotes_state == IN_QUOTES) + *quotes_state = 0; + else + *quotes_state = IN_QUOTES; + } + ((char *)expand->content)[i_exp++] = content[(*i)++]; + } + return (expand); +} + +static t_list *content_expand(char *content, int *i) { t_list *expand; - char *tmp; - int i_tmp; - tmp = ft_calloc(ft_strlen(&content[*i]) + 1, 1); - if (!tmp) - return (NULL); expand = ft_lstnew(NULL); if (!expand) - return (ft_retp_free(NULL, tmp, free)); + return (NULL); + expand->content = env_var_expansion(content, i); + if (!expand->content) + { + free(expand); + return (NULL); + } + return (expand); +} + +static char *retrieve_var(char *content, int *i); + +static char *env_var_expansion(char *content, int *i) +{ + char *expansion; + (*i)++; // skip '$' if (content[*i] == '?') { (*i)++; - expand->content = ft_itoa(get_last_exit_status()); - return (ft_retp_free(expand, tmp, free)); + expansion = ft_itoa(get_last_exit_status()); } - else if (content[*i] != '_' && !ft_isalpha(content[*i])) + else if (content[*i] == '_' || ft_isalpha(content[*i])) + expansion = retrieve_var(content, i); + else { - tmp[0] = '$'; - expand->content = tmp; - return (expand); + expansion = ft_calloc(1 + 1, 1); + if (!expansion) + return (NULL); + expansion[0] = '$'; } - i_tmp = 0; + return (expansion); +} + +static char *retrieve_var(char *content, int *i) +{ + char *expansion; + char *tmp; + int i_exp; + + expansion = ft_calloc(ft_strlen(&content[*i - 1]) + 1, 1); // *i - 1 for '$' skip + if (!expansion) + return (NULL); + i_exp = 0; while (content[*i] == '_' || ft_isalnum(content[*i])) - tmp[i_tmp++] = content[(*i)++]; - expand->content = getenv(tmp); - free(tmp); - if (expand->content) - expand->content = ft_strdup(expand->content); - return (expand); + expansion[i_exp++] = content[(*i)++]; + tmp = getenv(expansion); + ft_free_null(&expansion); + if (tmp) + expansion = ft_strdup(tmp); + else + expansion = ft_calloc(1, 1); + return (expansion); } /* diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/expansions.c similarity index 69% rename from srcs/parsing/expansions/words_expansions.c rename to srcs/parsing/expansions/expansions.c index 58e58fe..8784695 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/expansions.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* words_expansions.c :+: :+: :+: */ +/* expansions.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/10 10:27:01 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:50:58 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ t_list *expand_token(char *content); char *rejoin_after_expand(t_list *expand_lst); -int new_token_for_each_field(char **fields, t_token **t); +int new_token_for_each_field(char **fields, t_token *t); // 1 - chaque bout dans un element d'une t_list // (telle quelle si non expand, ou VARIABLE de env) @@ -25,28 +25,43 @@ int new_token_for_each_field(char **fields, t_token **t); // (ft_lstadd_front() sur le token original, puis set le token orignal à : // t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing) -int words_expansions(t_token *token_list) +int expansions(t_token *t, t_cmd **pipeline) { - while (token_list) + int i; + t_token *next_token; + + i = 0; + while (t) { - if (token_list->id == T_WORD) - token_expansions(&token_list); - token_list = token_list->next; + if (t->id == '|') + i++; + if (!pipeline[i]->error && t->id == T_WORD) + { + next_token = t->next; + if (!token_expansions(t)) + { + pipeline[i]->error = EXIT_EXPANSION; + } + while (t != next_token) + t = t->next; + } + else + t = t->next; } return (1); } -int token_expansions(t_token **t) +int token_expansions(t_token *t) { void *tmp; char **tmp_split; // 1 - tmp = expand_token((*t)->content); + tmp = (t_list*)expand_token(t->content); if (!tmp) return (0); // 2 - tmp = rejoin_after_expand(tmp); + tmp = (char*)rejoin_after_expand(tmp); if (!tmp) return (0); // 3 @@ -55,9 +70,9 @@ int token_expansions(t_token **t) if (!tmp_split) return (0); // 4 - tmp = ft_dup_2d_arr(tmp_split, (t_dup_f)ft_strdup_quotes); - ft_free_2d_arr(tmp_split); - tmp_split = tmp; + tmp = tmp_split; + tmp_split = ft_dup_2d_arr(tmp_split, (t_dup_f)ft_strdup_quotes); + ft_free_2d_arr(tmp); if (!tmp_split) return (0); // 5 diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index 8a285f8..937d50f 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -6,15 +6,15 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/10 10:27:26 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:50:36 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static t_token *insert_tokens(t_token *t, t_token *insert_lst); +static void insert_tokens(t_token *t, t_token *insert_lst); -int new_token_for_each_field(char **fields, t_token **t) +int new_token_for_each_field(char **fields, t_token *t) { t_token head; t_token *insert_lst; @@ -38,11 +38,11 @@ int new_token_for_each_field(char **fields, t_token **t) i++; } free(fields); - *t = insert_tokens(*t, head.next); + insert_tokens(t, head.next); return (1); } -static t_token *insert_tokens(t_token *t, t_token *insert_lst) +static void insert_tokens(t_token *t, t_token *insert_lst) { t_token *tmp; t_token *insert_lst_last; @@ -50,12 +50,12 @@ static t_token *insert_tokens(t_token *t, t_token *insert_lst) t->id = 0; ft_free_null(&t->content); if (!insert_lst) - return (t); + return ; tmp = t->next; t->next = insert_lst; insert_lst_last = (t_token *)ft_lstlast((t_list *)insert_lst); insert_lst_last->next = tmp; - return (insert_lst_last); + //return (insert_lst_last); // return inutile pour reusinage } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 6234c12..7d48cc3 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,12 +6,39 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/12/10 10:26:31 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:50:16 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +void save_redirections_words(t_token *t); + +t_cmd **parsing(t_token *token_list) +{ + t_cmd **pipeline; + + if (!valid_syntax(token_list)) + return (NULL); + + // 2.9.1 - 1) Save Words + save_redirections_words(token_list); + // Struct CMD alloc + pipeline = pipeline_alloc(1 + count_pipes(token_list)); + if (!pipeline) + return (NULL); + // 2.9.1 - 2) Expansion + if (!expansions(token_list, pipeline)) + return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); + // 2.9.1 - 3) Redirection + if (!redirections(token_list, pipeline)) + return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); + // Struct CMD fill + if (!pipeline_fill_argv(token_list, pipeline)) + return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); + return (pipeline); +} + void save_redirections_words(t_token *t) { while (t) @@ -26,62 +53,20 @@ void save_redirections_words(t_token *t) } } -void print_pipeline(t_cmd **pipeline) -{ - int i; +/* + 2.9.1 Simple Commands + 2.9.1 - 1) Save Words + 2.9.1 - 2) Expansion + 2.9.1 - 3) Redirection +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +#tag_18_09_01 +*/ - i = 0; - while (pipeline[i]) - { - printf("CMD %i, fd_in=%i, fd_out=%i\n", i, pipeline[i]->fd_in, pipeline[i]->fd_out); - ft_putstr_fd(" |", 1); - print_matrix(pipeline[i]->argv, "|\n |"); - i++; - if (pipeline[i]) - ft_putstr_fd("----------------\n", 1); - } -} - -t_cmd **parsing(t_token *token_list) -{ - t_cmd **pipeline; - - if (!valid_syntax(token_list)) - return (NULL); - - // 2.9.1 - 1) Save Words - save_redirections_words(token_list); - - // 2.9.1 - 2) Expansion - // TEST TOKENS PRINT - //ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); - //ft_lstprint((t_list *)token_list, 1); - // - // getenv() ne va pas fonctionner avec le changement d'environnement prévu jusqu'ici. - // TODO : Revoir le changement d'environnement (avec extern char **environ ?) - // OU Integrer un equivalent perso comme dans pipex - if (!words_expansions(token_list)) - return (NULL); - // - //ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1); - //ft_lstprint((t_list *)token_list, 1); - - // Struct CMD alloc - pipeline = pipeline_alloc(1 + count_pipes(token_list)); - if (!pipeline) - return (NULL); - - // 2.9.1 - 3) Redirection - if (!redirections(token_list, pipeline)) - return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); - - // Struct CMD fill - if (!pipeline_fill_argv(token_list, pipeline)) - return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); - //print_pipeline(pipeline); - - return (pipeline); -} +/* + 2.10 Shell Grammar +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +#tag_18_10 +*/ /* ------------------------------------------------------- The grammar symbols diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c index 31ec976..fa8ae6e 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/12/10 10:25:54 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:49:53 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ int here_doc(char *delimiter) ret = here_doc_write(delimiter, here_doc); free(delimiter); if (close(here_doc) == -1) - ft_perror_io("close() ", TMP_HERE_DOC); + shell_perror(TMP_HERE_DOC, ": ", "", 0); if (ret != 0) { if (unlink(TMP_HERE_DOC) == -1) @@ -46,7 +46,7 @@ int here_doc(char *delimiter) } here_doc = open(TMP_HERE_DOC, O_RDONLY); if (here_doc == -1) - ft_perror_io("open() ", TMP_HERE_DOC); + shell_perror(TMP_HERE_DOC, ": ", "", 0); if (unlink(TMP_HERE_DOC) == -1) return (ft_reti_perror_io(-1, "unlink() ", TMP_HERE_DOC)); return (here_doc); diff --git a/srcs/parsing/redirections/redirections.c b/srcs/parsing/redirections/redirections.c index 1754daf..18b51b2 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/12/10 10:25:34 by hulamy ### ########.fr */ +/* Updated: 2021/12/16 14:49:28 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ int here_doc(char *delimiter); static int redirect_cmd_input(t_token *t, t_cmd *cmd); static int redirect_cmd_output(t_token *t, t_cmd *cmd); +static int expand_redirection(t_token *t); int redirections(t_token *t, t_cmd **pipeline) { @@ -24,6 +25,8 @@ int redirections(t_token *t, t_cmd **pipeline) i = 0; while (t) { + if (t->id == '|') + i++; if (!pipeline[i]->error) { if (t->id == '<' || t->id == T_DLESS) @@ -37,8 +40,6 @@ int redirections(t_token *t, t_cmd **pipeline) return (0); } } - if (t->id == '|') - i++; t = t->next; } return (1); @@ -51,15 +52,15 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) perror("close()"); if (t->id == '<') { - // TODO : Expansion + quote removal sur le word t->next->content. - // si plus d'un champ ou aucun champ aprés expansion, - // message d'erreur comme bash "bash: $VAR: ambiguous redirect" - // OU prise en compte seulement du premier champ. - //EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + if (!expand_redirection(t)) + { + cmd->error = EXIT_REDIRECTION; + return (1); + } cmd->fd_in = open(t->next->content, O_RDONLY); if (cmd->fd_in == -1) { - ft_perror_io("open() ", t->next->content); // todo error + shell_perror(t->next->content, ": ", "", 0); cmd->error = EXIT_REDIRECTION; } } @@ -68,7 +69,7 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) cmd->fd_in = here_doc(t->next->content); if (cmd->fd_in == -1) { - ft_putstr_fd("minishell: heredoc error\n", 2); + shell_error("heredoc error", ": ", "", 0); cmd->error = EXIT_REDIRECTION; } else if (cmd->fd_in > EXIT_SIGNAL) @@ -87,11 +88,11 @@ static int redirect_cmd_output(t_token *t, t_cmd *cmd) if (cmd->fd_out != STDOUT_FILENO) if (close(cmd->fd_out) == -1) perror("close()"); - // TODO : Expansion + quote removal sur le word t->next->content. - // si plus d'un champ ou aucun champ aprés expansion, - // message d'erreur comme bash "bash: $VAR: ambiguous redirect" - // OU prise en compte seulement du premier champ. - //EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + if (!expand_redirection(t)) + { + cmd->error = EXIT_REDIRECTION; + return (1); + } flags = O_WRONLY | O_CREAT; if (t->id == '>') flags = flags | O_TRUNC; @@ -100,8 +101,37 @@ static int redirect_cmd_output(t_token *t, t_cmd *cmd) cmd->fd_out = open(t->next->content, flags, S_IRWXU); if (cmd->fd_out == -1) { - ft_perror_io("open() ", t->next->content); + shell_perror(t->next->content, ": ", "", EXIT_REDIRECTION); cmd->error = EXIT_REDIRECTION; } return (1); } + +static int expand_redirection(t_token *t) +{ + t_token *head; + t_token *next_token; + int ret; + + ret = 1; + head = t; + t = t->next; + next_token = t->next; + t->next = NULL; + if (!token_expansions(t)) + { + ((t_token *)ft_lstlast((t_list *)head))->next = next_token; + return (0); + } + head->next = t->next; + free(t); + if (head->next) + head->next->id = T_REDIRECTION_WORD; // Eventuellement a integrer dans token_expansions() + if (ft_lstsize((t_list *)head->next) != 1) + { + ret = 0; + shell_error("", "", "ambiguous redirect", 0); + } + ((t_token *)ft_lstlast((t_list *)head))->next = next_token; + return (ret); +} diff --git a/srcs/terminal.c b/srcs/terminal.c deleted file mode 100644 index b33f969..0000000 --- a/srcs/terminal.c +++ /dev/null @@ -1,76 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* terminal.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: lperrey +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2021/10/27 00:10:04 by lperrey #+# #+# */ -/* Updated: 2021/10/30 14:17:16 by lperrey ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -#define CTRL_C 03 -#define CTRL_D 04 -#define CTRL_BACKSLASH 034 - -int set_terminal_attributes(struct termios *ori_termios, - struct termios *interactive_termios, - int *termios_changed) -{ - tcgetattr(STDIN_FILENO, ori_termios); - *interactive_termios = *ori_termios; - - interactive_termios->c_cc[VINTR] = CTRL_D; - interactive_termios->c_cc[VEOF] = CTRL_C; - - //interactive_termios->c_cc[VQUIT] = CTRL_C; - //interactive_termios->c_cc[VEOF] = CTRL_BACKSLASH; - - //interactive_termios->c_cc[VEOL] = CTRL_C; - - *termios_changed = 1; - tcsetattr(STDIN_FILENO, TCSANOW, interactive_termios); - - return (1); -} - - //printf("STDIN_FILENO = %s\n ", ttyname(STDIN_FILENO)); - //printf("STDOUT_FILENO = %s\n ", ttyname(STDOUT_FILENO)); - //printf("STDERR_FILENO = %s\n ", ttyname(STDERR_FILENO)); - //ft_putendl_fd(ttyname(STDIN_FILENO), 1); - //ft_putendl_fd(ttyname(STDOUT_FILENO), 1); - //ft_putendl_fd(ttyname(STDERR_FILENO), 1); - // ft_printf("BEFORE\n"); - // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); - // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); - // ft_printf("AFTER\n"); - // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); - // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); - -void wip_test() -{ - char term_desc[2048]; - char *term_type; - int term_width; - int term_height; - int ret; - - term_type = getenv("TERM"); - if (term_type == 0) - ft_putstr_fd("Specify a terminal type with `setenv TERM '.\n", 2); - ret = tgetent(term_desc, term_type); - if (ret < 0) - ft_putstr_fd("Could not access the termcap data base.\n", 2); - if (ret == 0) - ft_putstr_fd("Terminal type `%s' is not defined.\n", 2); - term_height = tgetnum ("li"); - term_width = tgetnum ("co"); - /* Extract information that termcap functions use. */ -/* temp = tgetstr ("pc", BUFFADDR); - PC = temp ? *temp : 0; - BC = tgetstr ("le", BUFFADDR); - UP = tgetstr ("up", BUFFADDR); */ -}