diff --git a/Makefile b/Makefile index bdedc6e..e596344 100644 --- a/Makefile +++ b/Makefile @@ -25,17 +25,18 @@ LIBS = -L $(LIBFT_D) -lft \ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a -SRCS = main.c init.c free.c generic.c \ +SRCS = main.c init.c free.c generic.c error_wrappers.c \ signals.c \ shell_loop.c shell_script.c \ lexing.c fill_token.c check_operators.c \ - parsing.c cmd_array.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 \ 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.h b/headers/minishell.h index 51eecc0..c08f78b 100644 --- a/headers/minishell.h +++ b/headers/minishell.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/03 19:14:46 by lperrey #+# #+# */ -/* Updated: 2021/10/26 14:53:32 by lperrey ### ########.fr */ +/* Updated: 2021/11/27 09:09:31 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,8 +38,8 @@ # include -# include "minishell_structs.h" # include "minishell_macro.h" +# include "minishell_structs.h" # include "minishell_term_colors.h" # include "minishell_user_macro.h" # include "minishell_prototypes.h" diff --git a/headers/minishell_macro.h b/headers/minishell_macro.h index 7ff7858..4803253 100644 --- a/headers/minishell_macro.h +++ b/headers/minishell_macro.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:55 by lperrey #+# #+# */ -/* Updated: 2021/10/30 22:32:48 by lperrey ### ########.fr */ +/* Updated: 2021/11/27 10:43:43 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,10 +18,37 @@ # define PROMPT_CHEVRON "> " # define PROMPT_EURO "\001€\002 \001\b\002" +# define EXIT_CMD_NOT_FOUND 127 +# define EXIT_CMD_NOT_EXE 126 +# define EXIT_SIGNAL 128 + +// 1 and 125 inclusive +# define EXIT_REDIRECTION 22 +# define EXIT_EXPANSION 33 + enum e_lexer_return { CONTINUE_TOKEN = 1, DELIMITE_TOKEN }; +enum e_token_id +{ + T_LESS = '<', + T_GREAT = '>', + T_PIPE = '|', + T_DLESS, + T_DGREAT, + T_WORD, + T_REDIRECTION_WORD +}; +// T_DLESS == '<<' +// T_DGREAT == '>>' + +enum e_quotes_state +{ + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + #endif diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 7823d42..2c5267d 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/12/02 00:37:39 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,11 +14,13 @@ # define MINISHELL_PROTOTYPES_H // variable globale -int switch_heredoc_sigint; +int g_switch_heredoc_sigint; +extern char **environ; // Init -int init(t_all *c, char *envp[]); -char **retrieve_path(char *envp[]); +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, :) @@ -29,7 +31,7 @@ void shell_loop(t_all *c); void shell_script(t_all *c); // Lexer -t_token *input_to_tokens(char *input); +t_token *lexing(char *input); // Parser t_cmd **parsing(t_token *token_list); @@ -37,18 +39,18 @@ int valid_syntax(t_token *token_list); int valid_token(t_token **token_list, enum e_token_id token_id); int valid_command_separator(const t_token *token_list); size_t count_pipes(t_token *token_list); -t_cmd **cmd_array_alloc(size_t cmd_nbr); -int cmd_array_fill_argv(t_token *token_list, t_cmd **cmd_arr); +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 redirections(t_token *token_list, t_cmd **cmd_arr); +int redirections(t_token *token_list, t_cmd **pipeline); // Exec int exec_cmd_line(t_all *c); int pipeline(t_all *c); int cmd_find_access(t_cmd *cmd, char *path[]); int cmd_exec_in_subshell(t_cmd *cmd, t_all *c); -void wait_subshell(pid_t last_cmd_pid, int *last_exit_status); +void wait_subshell(pid_t last_cmd_pid); int simple_command_builtin(t_cmd *cmd, t_all *c); // Builtins @@ -62,11 +64,14 @@ int builtin_echo(int argc, char *argv[], t_all *c); int getenv_position(char **envp, char *name); // Free -int free_exit(t_all *c, int exit_status); +int exit_free(t_all *c, int exit_status); void free_pipeline(t_cmd **pipeline_ptr[]); void close_pipeline_fd(t_cmd *pipeline[]); typedef void (*t_free_f)(void *); // generic +// Error wrappers +void shell_error(char *s1, char *s2); + // Generic char *ft_strjoinfree(char *s1, char *s2); char *ft_strjoinfree_s1(char *s1, const char *s2); @@ -78,11 +83,12 @@ 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); -t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); +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_split_quotes(char const *s, char c); char *ft_strdup_quotes(const char *s); @@ -91,4 +97,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/headers/minishell_structs.h b/headers/minishell_structs.h index 4e64f91..18f55ee 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,28 +6,14 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/11/25 16:33:56 by hulamy ### ########.fr */ +/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_STRUCTS_H # define MINISHELL_STRUCTS_H -struct s_all *g_all; - -enum e_token_id -{ - T_TOKEN = 0, - T_LESS = '<', - T_GREAT = '>', - T_PIPE = '|', - T_DLESS, - T_DGREAT, - T_WORD, - T_REDIRECTION_WORD -}; -// T_DLESS == '<<' -// T_DGREAT == '>>' +struct s_all; typedef struct s_token { @@ -42,7 +28,7 @@ typedef struct s_cmd { char **argv; char *path; - t_builtin_f builtin_func; + t_builtin_f builtin_f; int fd_in; int fd_out; pid_t pid; @@ -51,13 +37,11 @@ typedef struct s_cmd typedef struct s_all { - t_cmd **cmd_arr; -// char **envp; + t_cmd **pipeline; char **path; char *prompt_base; char *prompt; t_token *token_list; - int last_exit_status; // struct termios ori_termios; // struct termios interactive_termios; // int termios_changed; diff --git a/ressources/parsing.md b/ressources/parsing.md deleted file mode 100644 index 0ef6fa7..0000000 --- a/ressources/parsing.md +++ /dev/null @@ -1 +0,0 @@ -https://raw.githubusercontent.com/kukinpower/minishell/master/images/3.png diff --git a/ressources/parsing.png b/ressources/parsing.png deleted file mode 100644 index d6ef34e..0000000 Binary files a/ressources/parsing.png and /dev/null differ diff --git a/srcs/builtins/cd.c b/srcs/builtins/cd.c index 714c1ee..1ceaafa 100644 --- a/srcs/builtins/cd.c +++ b/srcs/builtins/cd.c @@ -1,9 +1,6 @@ #include "minishell.h" -// a integrer dans header -char *init_prompt(char *prompt_base); - int builtin_cd(int argc, char *argv[], t_all *c) { (void)argc; diff --git a/srcs/builtins/env.c b/srcs/builtins/env.c index 1b5b0b5..6642079 100644 --- a/srcs/builtins/env.c +++ b/srcs/builtins/env.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 05:01:26 by lperrey #+# #+# */ -/* Updated: 2021/11/25 19:01:13 by hulamy ### ########.fr */ +/* Updated: 2021/11/27 11:18:55 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,11 +14,8 @@ int builtin_env(int argc, char *argv[], t_all *c) // WIP { - extern char **environ; - (void)argc; (void)argv; - //ft_putendl_arr_fd(c->envp, 1); ft_putendl_arr_fd(environ, 1); return (0); } diff --git a/srcs/builtins/exit.c b/srcs/builtins/exit.c index e6f6ca5..7a726ea 100644 --- a/srcs/builtins/exit.c +++ b/srcs/builtins/exit.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 05:01:22 by lperrey #+# #+# */ -/* Updated: 2021/10/22 14:49:01 by lperrey ### ########.fr */ +/* Updated: 2021/11/29 12:43:47 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,7 @@ int builtin_exit(int argc, char *argv[], t_all *c) // WIP unsigned char status; int i; - status = c->last_exit_status; + status = get_last_exit_status(); if (argc > 2) return (ft_reti_print(1, "exit: too many arguments\n", 2)); if (argc == 2) @@ -38,5 +38,5 @@ int builtin_exit(int argc, char *argv[], t_all *c) // WIP } status = ft_atoi(argv[1]); } - return (free_exit(c, status)); + return (exit_free(c, status)); } diff --git a/srcs/builtins/export.c b/srcs/builtins/export.c index 3385e49..6e190b7 100644 --- a/srcs/builtins/export.c +++ b/srcs/builtins/export.c @@ -1,7 +1,7 @@ #include "minishell.h" -int getenv_position(char **envp, char *name) +int getenv_position(char **envp, char *name) // TODO : virer arg envp et utiliser "extern **environ" à la place { int i; @@ -13,7 +13,6 @@ int getenv_position(char **envp, char *name) int builtin_export(int argc, char *argv[], t_all *c) { - extern char **environ; char **var; int env_position; @@ -26,8 +25,8 @@ int builtin_export(int argc, char *argv[], t_all *c) if (environ[env_position] == '\0') environ = ft_resize_2d_arr(environ, 1); environ[env_position] = ft_strdup(argv[1]); - if (!ft_strncmp(var[0], "PATH", 4 + 1)) - c->path = retrieve_path(environ); + if (!ft_strncmp(var[0], "PATH", 4 + 1)) // TODO : NON. Ce n'est pas la fin de la string donc "strlen() + 1" n'est pas adapté + c->path = retrieve_path(); // free var return (0); } diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c index 2db1c14..755c76f 100644 --- a/srcs/builtins/unset.c +++ b/srcs/builtins/unset.c @@ -3,21 +3,22 @@ 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/error_wrappers.c b/srcs/error_wrappers.c new file mode 100644 index 0000000..df1d6f2 --- /dev/null +++ b/srcs/error_wrappers.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error_wrappers.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/12/01 17:16:30 by lperrey #+# #+# */ +/* Updated: 2021/12/01 17:19:02 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_error(char *s1, char *s2) +{ + char *prefix; + + prefix = "minishell: "; + write(STDERR_FILENO, prefix, ft_strlen(prefix)); + if (s1) + write(STDERR_FILENO, s1, ft_strlen(s1)); + if (s2) + write(STDERR_FILENO, s2, ft_strlen(s2)); + write(STDERR_FILENO, "\n", 1); +} diff --git a/srcs/exec/exec_cmd_line.c b/srcs/exec/exec_cmd_line.c index bbd417c..3becd61 100644 --- a/srcs/exec/exec_cmd_line.c +++ b/srcs/exec/exec_cmd_line.c @@ -6,20 +6,24 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/18 13:29:25 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 16:07:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01 - int exec_cmd_line(t_all *c) { if (!pipeline(c)) { - free_pipeline(&c->cmd_arr); + free_pipeline(&c->pipeline); return (0); } return (1); } + +/* + 2.9.1 Simple Commands - Command Search and Execution +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +#tag_18_09_01_01 +*/ diff --git a/srcs/exec/find_access.c b/srcs/exec/find_access.c index 2f2f53a..fbe16e5 100644 --- a/srcs/exec/find_access.c +++ b/srcs/exec/find_access.c @@ -6,19 +6,24 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/18 13:20:20 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 17:16:55 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static int search_cmd_path(char *cmd_name, char **cmd_path, - char *path[]); + char *path[]); static t_builtin_f search_builtin(char *cmd_name); static int handle_access_error(char *file_name); -// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 -// faire des test sur la valeur de errno selon les cas (if directory, if pathname invalid, ...) +/* + 2.8.2 Exit Status for Commands +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +#tag_18_08_02 +*/ + +// TODO : faire des test sur la valeur de errno selon les cas (if directory, if pathname invalid, ...) int cmd_find_access(t_cmd *cmd, char *path[]) { @@ -29,29 +34,26 @@ int cmd_find_access(t_cmd *cmd, char *path[]) else { cmd->path = ft_strdup(cmd->argv[0]); - if (!cmd->path) + if (!cmd->path) return (0); } } else { - cmd->builtin_func = search_builtin(cmd->argv[0]); - if (cmd->builtin_func) + cmd->builtin_f = search_builtin(cmd->argv[0]); + if (cmd->builtin_f) return (1); if (search_cmd_path(cmd->argv[0], &cmd->path, path) == -1) return (0); if (!cmd->path) { - cmd->error = 127; - ft_putstr_fd("minishell: ", 2); - ft_putstr_fd(cmd->argv[0], 2); - ft_putstr_fd(": command not found\n", 2); + cmd->error = EXIT_CMD_NOT_FOUND; + shell_error(cmd->argv[0], ": command not found"); } } return (1); } - static int search_cmd_path(char *cmd_name, char **cmd_path, char *path[]) { int i; @@ -70,10 +72,7 @@ static int search_cmd_path(char *cmd_name, char **cmd_path, char *path[]) if (access(*cmd_path, X_OK) == 0) break ; else - { - free(*cmd_path); - *cmd_path = NULL; // TODO : free_null() - } + ft_free_null(cmd_path); i++; } free(cmd_name); @@ -107,7 +106,7 @@ static int handle_access_error(char *file_name) ft_perror_io("minishell: ", file_name); errno = tmp; if (errno == EACCES) - return (127); + return (EXIT_CMD_NOT_FOUND); return (1); - // 126 + // 126 / EXIT_CMD_NOT_EXE } diff --git a/srcs/exec/pipeline.c b/srcs/exec/pipeline.c index 21e9d46..6646d52 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/11/18 23:08:16 by hulamy ### ########.fr */ +/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,15 +18,15 @@ static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c); int pipeline(t_all *c) { - if (!open_pipes(c->cmd_arr)) + if (!open_pipes(c->pipeline)) return (0); - if (!pipeline_find_access(c->cmd_arr, c->path)) + if (!pipeline_find_access(c->pipeline, c->path)) return (0); - if (ft_2d_arrlen(c->cmd_arr) == 1 && c->cmd_arr[0]->builtin_func) - simple_command_builtin(c->cmd_arr[0], c); + if (ft_2d_arrlen(c->pipeline) == 1 && c->pipeline[0]->builtin_f) + simple_command_builtin(c->pipeline[0], c); else - wait_subshell(pipeline_exec(c->cmd_arr, c), &c->last_exit_status); - free_pipeline(&c->cmd_arr); + wait_subshell(pipeline_exec(c->pipeline, c)); + free_pipeline(&c->pipeline); return (1); } @@ -69,8 +69,6 @@ static int pipeline_find_access(t_cmd *pipeline[], char *path[]) return (1); } -// TODO : Change exit status as in documentation : -// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c) { int i; @@ -83,13 +81,13 @@ static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c) { ret = cmd_exec_in_subshell(pipeline[i], c); if (ret != EXIT_SUCCESS) - free_exit(c, ret); + exit_free(c, ret); } i++; } - close_pipeline_fd(c->cmd_arr); + close_pipeline_fd(c->pipeline); i -= 1; if (pipeline[i]->error) - c->last_exit_status = pipeline[i]->error; + set_last_exit_status(pipeline[i]->error); return (pipeline[i]->pid); } diff --git a/srcs/exec/simple_cmd_builtin.c b/srcs/exec/simple_cmd_builtin.c index 902dfa8..a97c95e 100644 --- a/srcs/exec/simple_cmd_builtin.c +++ b/srcs/exec/simple_cmd_builtin.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/18 14:08:56 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ int simple_command_builtin(t_cmd *cmd, t_all *c) if (dup2(cmd->fd_out, STDOUT_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); } - c->last_exit_status = cmd->builtin_func(ft_2d_arrlen(cmd->argv), cmd->argv, c); + set_last_exit_status(cmd->builtin_f(ft_2d_arrlen(cmd->argv), cmd->argv, c)); if (!restore_stdio(stdin_dup, stdout_dup)) return (EXIT_FAILURE); return (EXIT_SUCCESS); diff --git a/srcs/exec/subshell_exec.c b/srcs/exec/subshell_exec.c index 721868e..273f9bf 100644 --- a/srcs/exec/subshell_exec.c +++ b/srcs/exec/subshell_exec.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/25 18:59:02 by hulamy ### ########.fr */ +/* Updated: 2021/12/01 16:49:37 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,8 +14,6 @@ int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) { - extern char **environ; - cmd->pid = fork(); if (cmd->pid == -1) perror("fork()"); @@ -29,10 +27,9 @@ int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) if (cmd->fd_out != STDOUT_FILENO) if (dup2(cmd->fd_out, STDOUT_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); - close_pipeline_fd(c->cmd_arr); - if (cmd->builtin_func) - free_exit(c, cmd->builtin_func(ft_2d_arrlen(cmd->argv), cmd->argv, c)); - //else if (execve(cmd->path, cmd->argv, c->envp) == -1) + close_pipeline_fd(c->pipeline); + if (cmd->builtin_f) + exit_free(c, cmd->builtin_f(ft_2d_arrlen(cmd->argv), cmd->argv, c)); else if (execve(cmd->path, cmd->argv, environ) == -1) return (ft_reti_perror_io(EXIT_FAILURE, "execve() ", cmd->argv[0])); } diff --git a/srcs/exec/subshell_wait.c b/srcs/exec/subshell_wait.c index d19a925..b5ae3b0 100644 --- a/srcs/exec/subshell_wait.c +++ b/srcs/exec/subshell_wait.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/18 23:09:46 by hulamy ### ########.fr */ +/* Updated: 2021/11/27 10:43:46 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ static int handle_wait_error(void); -void wait_subshell(pid_t last_cmd_pid, int *last_exit_status) +void wait_subshell(pid_t last_cmd_pid) { int wstatus; int ret; @@ -25,11 +25,11 @@ void wait_subshell(pid_t last_cmd_pid, int *last_exit_status) if (waitpid(last_cmd_pid, &wstatus, 0) == -1) perror("waitpid()"); if (WIFEXITED(wstatus)) - *last_exit_status = WEXITSTATUS(wstatus); + set_last_exit_status(WEXITSTATUS(wstatus)); if (WIFSIGNALED(wstatus)) { write(STDIN_FILENO, "\n", 1); - *last_exit_status = 128 + WTERMSIG(wstatus); + set_last_exit_status(EXIT_SIGNAL + WTERMSIG(wstatus)); } } ret = 0; diff --git a/srcs/free.c b/srcs/free.c index ba0d477..285350b 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -6,20 +6,20 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */ -/* Updated: 2021/11/25 16:36:39 by hulamy ### ########.fr */ +/* Updated: 2021/12/02 00:42:33 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int free_exit(t_all *c, int exit_status) +int exit_free(t_all *c, int exit_status) { 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); + free_pipeline(&c->pipeline); //if (c->termios_changed) // tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); rl_clear_history(); diff --git a/srcs/generic.c b/srcs/generic.c index 002eec3..602be02 100644 --- a/srcs/generic.c +++ b/srcs/generic.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ -/* Updated: 2021/11/14 08:27:40 by lperrey ### ########.fr */ +/* Updated: 2021/11/30 18:51:00 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -84,7 +84,7 @@ size_t ft_2d_arrlen(void *ptr) // Replace ft_arrlen() len++; return (len); } - +/* char **ft_dup_2d_char_arr(char **ptr) // Superflu si ft_dup_2d_arr() fonctionne { unsigned int i; @@ -105,7 +105,7 @@ char **ft_dup_2d_char_arr(char **ptr) // Superflu si ft_dup_2d_arr() fonctionne } 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 *)) @@ -114,7 +114,7 @@ void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) char **arr; char **new_arr; - new_arr = malloc((ft_2d_arrlen(ptr) + 1) * sizeof (void *)); + new_arr = ft_calloc(ft_2d_arrlen(ptr) + 1, sizeof (void *)); if (!new_arr) return (NULL); arr = (char **)ptr; @@ -126,7 +126,6 @@ void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); i++; } - new_arr[i] = NULL; return (new_arr); } @@ -137,6 +136,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]) @@ -174,7 +175,8 @@ t_list *ft_lstbeforelast(t_list *lst) return (lst); } -t_list *ft_lstnew_generic(size_t lst_size, size_t content_size) +/* 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; @@ -210,3 +212,9 @@ int ft_reti_perror_io(int ret, char *err_str, char *io_file) perror(io_file); return (ret); } + +void ft_free_null(void *ptr) +{ + free(*(char**)ptr); + *(char**)ptr = NULL; +} diff --git a/srcs/init.c b/srcs/init.c index a5c9e6f..92f24a6 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,29 +6,26 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/11/25 23:59:33 by hulamy ### ########.fr */ +/* Updated: 2021/12/02 01:38:22 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static char *init_prompt_base(void); -// pas static si utilisee par cd -//static char *init_prompt(char *prompt_base); -char *init_prompt(char *prompt_base); +static int init_readline_hook(void); -//int init(t_all *c, char *envp[]) -int init(t_all *c, char **environ) +int init(t_all *c) { - (void)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")); - //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 + rl_outstream = stderr; + rl_startup_hook = init_readline_hook; + readline(NULL); + rl_startup_hook = NULL; + environ = ft_dup_2d_arr(environ, (t_dup_f)ft_strdup); + if (!environ) + return (ft_reti_perror(0, "ft_dup_2d_arr(environ) error")); + c->path = retrieve_path(); c->prompt_base = init_prompt_base(); if (!c->prompt_base) return (ft_reti_perror(0, "init_prompt_base() error")); @@ -40,14 +37,11 @@ int init(t_all *c, char **environ) } // done : TODO : Un appel à builtin_export() modifiant $PATH doit aussi entrainer un appel à "c->path = retrieve_path()" -// changer le prototype si utilise pas envp -char **retrieve_path(char *envp[]) +char **retrieve_path(void) { char *path; char **path_split; - (void)envp; - //path = search_env_var(envp, "PATH"); // A reprendre du projet pipex si besoin de remplacer getenv() path = getenv("PATH"); if (!path) return (ft_retp_print(NULL, "minishell: Warning, $PATH not set\n", 2)); @@ -77,7 +71,6 @@ static char *init_prompt_base(void) // WIP, error return TODO return (prompt_base); } -//static char *init_prompt(char *prompt_base) // WIP, error return TODO char *init_prompt(char *prompt_base) // WIP, error return TODO { char *prompt; @@ -86,3 +79,13 @@ char *init_prompt(char *prompt_base) // WIP, error return TODO prompt = ft_strjoinfree_s1(prompt, TERM_RESET U_PROMPT_END); return (prompt); } + +/* +** set rl_startup_hook with this, for init COLUMNS and LINES variables +** and prevent leak/double_free with **environ +*/ +static int init_readline_hook(void) +{ + rl_done = 1; + return (0); +} diff --git a/srcs/last_exit_status.c b/srcs/last_exit_status.c new file mode 100644 index 0000000..13da226 --- /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 20:48:11 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 (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/lexing/fill_token.c b/srcs/lexing/fill_token.c index 4367689..d6f74dd 100644 --- a/srcs/lexing/fill_token.c +++ b/srcs/lexing/fill_token.c @@ -6,52 +6,31 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/30 22:35:01 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 16:00:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int check_operators(t_token *t, char *input, int *i, int *t_i); +int check_operators(t_token *t, char *input, int *i, int *t_i); -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; +static int quoting(int *quotes_state, char *input, int *i); int fill_token(t_token *t, char *input, int *i, int *t_i) { - static int in_quotes = 0; + static int quotes_state = 0; - // operators - if (!in_quotes) + if (!quotes_state) { if (check_operators(t, input, i, t_i) == DELIMITE_TOKEN) return (DELIMITE_TOKEN); } - // quoting - if (input[*i] == '\'' && in_quotes != IN_DQUOTES) + if (quoting("es_state, input, i)) { t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_QUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\'')) // if closed quotes - in_quotes = IN_QUOTES; return (CONTINUE_TOKEN); } - else if (input[*i] == '\"' && in_quotes != IN_QUOTES) - { - t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_DQUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\"')) // if closed dquotes - in_quotes = IN_DQUOTES; - return (CONTINUE_TOKEN); - } - // blanks - if (!in_quotes && (input[*i] == ' ' || input[*i] == '\t')) + if (!quotes_state && (input[*i] == ' ' || input[*i] == '\t')) { while (input[*i] == ' ' || input[*i] == '\t') (*i)++; @@ -62,17 +41,23 @@ int fill_token(t_token *t, char *input, int *i, int *t_i) return (CONTINUE_TOKEN); } -/* -https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 -1 - OK -2 - OK -3 - OK -4 - OK -5 - OK / SEMI-OSEF -6 - OK -7 - OK -8 - OK -9 - OSEF -10 - OK - -*/ +static int quoting(int *quotes_state, char *input, int *i) +{ + if (input[*i] == '\'' && *quotes_state != IN_DQUOTES) + { + if (*quotes_state == IN_QUOTES) + *quotes_state = 0; + else if (ft_strchr(&input[*i + 1], '\'')) + *quotes_state = IN_QUOTES; + return (CONTINUE_TOKEN); + } + else if (input[*i] == '\"' && *quotes_state != IN_QUOTES) + { + if (*quotes_state == IN_DQUOTES) + *quotes_state = 0; + else if (ft_strchr(&input[*i + 1], '\"')) + *quotes_state = IN_DQUOTES; + return (CONTINUE_TOKEN); + } + return (0); +} diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c index 920e277..5914fb4 100644 --- a/srcs/lexing/lexing.c +++ b/srcs/lexing/lexing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/11/07 03:18:38 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 14:54:22 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,19 +14,18 @@ int fill_token(t_token *t, char *input, int *i, int *t_i); -static t_token *alloc_token(size_t content_len); // TODO, a remplacer par ft_lstnew_generic() static int tokenize_input(t_token *t, char *input, size_t input_len); -t_token *input_to_tokens(char *input) +t_token *lexing(char *input) { t_token *t_head; t_token *t_tmp; size_t input_len; input_len = ft_strlen(input); - t_head = alloc_token(input_len); + t_head = ft_lstnew_generic(sizeof(t_token), input_len + 1); if (!t_head) - return (ft_retp_perror(NULL, "alloc_token() error")); + return (ft_retp_perror(NULL, "ft_lstnew_generic() error")); if (!tokenize_input(t_head, input, input_len)) return (ft_lstclear((t_list **)&t_head, free)); t_tmp = (t_token *)ft_lstbeforelast((t_list *)t_head); @@ -38,19 +37,6 @@ t_token *input_to_tokens(char *input) return (t_head); } -static t_token *alloc_token(size_t content_len) -{ - t_token *token; - - token = ft_calloc(1, sizeof (*token)); - if (!token) - return (NULL); - token->content = ft_calloc(content_len + 1, 1); - if (!token->content) - return (ft_retp_free(NULL, token, free)); - return (token); -} - static int tokenize_input(t_token *t, char *input, size_t input_len) { int i; @@ -64,9 +50,9 @@ static int tokenize_input(t_token *t, char *input, size_t input_len) { if (!t->id) t->id = T_WORD; - t->next = alloc_token(input_len - i); + t->next = ft_lstnew_generic(sizeof(t_token), input_len + 1 - i); if (!t->next) - return (ft_reti_perror(0, "alloc_token() error")); + return (ft_reti_perror(0, "ft_lstnew_generic() error")); t = t->next; t_i = 0; } @@ -75,3 +61,8 @@ static int tokenize_input(t_token *t, char *input, size_t input_len) t->id = T_WORD; return (1); } + +/* +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +#tag_18_03 +*/ diff --git a/srcs/main.c b/srcs/main.c index 67f752c..e28ea1c 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,27 +6,24 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/25 19:48:07 by hulamy ### ########.fr */ +/* Updated: 2021/11/29 12:43:34 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -//int main(int argc, char *argv[], char *envp[]) int main(int argc, char *argv[]) { t_all c; - extern char **environ; (void)argc; (void)argv; -// if (!init(&c, envp)) - if (!init(&c, environ)) - free_exit(&c, EXIT_FAILURE); + if (!init(&c)) + exit_free(&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/cmd_array.c b/srcs/parsing/create_pipeline.c similarity index 63% rename from srcs/parsing/cmd_array.c rename to srcs/parsing/create_pipeline.c index b57386c..851e172 100644 --- a/srcs/parsing/cmd_array.c +++ b/srcs/parsing/create_pipeline.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* cmd_array.c :+: :+: :+: */ +/* create_pipeline.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/02 22:46:23 by lperrey #+# #+# */ -/* Updated: 2021/11/14 12:24:39 by lperrey ### ########.fr */ +/* Updated: 2021/11/29 12:29:27 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,47 +28,47 @@ size_t count_pipes(t_token *t) return (count); } -t_cmd **cmd_array_alloc(size_t cmd_nbr) +t_cmd **pipeline_alloc(size_t cmd_nbr) { - t_cmd **cmd_arr; + t_cmd **pipeline; size_t i; - cmd_arr = ft_calloc(cmd_nbr + 1, sizeof (void *)); - if (!cmd_arr) - return (ft_retp_perror(NULL, "cmd_array_alloc()")); + pipeline = ft_calloc(cmd_nbr + 1, sizeof (void *)); + if (!pipeline) + return (ft_retp_perror(NULL, "pipeline_alloc()")); i = 0; while (i < cmd_nbr) { - cmd_arr[i] = ft_calloc(1, sizeof (*cmd_arr[i])); - if (!cmd_arr[i]) + pipeline[i] = ft_calloc(1, sizeof (*pipeline[i])); + if (!pipeline[i]) { - ft_free_2d_arr(cmd_arr); - return (ft_retp_perror(NULL, "cmd_array_alloc()")); + ft_free_2d_arr(pipeline); + return (ft_retp_perror(NULL, "pipeline_alloc()")); } - cmd_arr[i]->fd_in = STDIN_FILENO; - cmd_arr[i]->fd_out = STDOUT_FILENO; + pipeline[i]->fd_in = STDIN_FILENO; + pipeline[i]->fd_out = STDOUT_FILENO; i++; } - return (cmd_arr); + return (pipeline); } -int cmd_array_fill_argv(t_token *t, t_cmd **cmd_arr) +int pipeline_fill_argv(t_token *t, t_cmd **pipeline) { size_t i; size_t arg_i; i = 0; - while (cmd_arr[i]) + while (pipeline[i]) { - cmd_arr[i]->argv = ft_calloc(cmd_words_count(t) + 1, sizeof (char *)); - if (!cmd_arr[i]->argv) - return (ft_reti_perror(0, "cmd_array_fill_argv()")); + pipeline[i]->argv = ft_calloc(cmd_words_count(t) + 1, sizeof (char *)); + if (!pipeline[i]->argv) + return (ft_reti_perror(0, "pipeline_fill_argv()")); arg_i = 0; while (t && t->id != '|') { if (t->id == T_WORD) { - cmd_arr[i]->argv[arg_i++] = t->content; + pipeline[i]->argv[arg_i++] = t->content; t->content = NULL; } t = t->next; diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c index 7885052..90ab62f 100644 --- a/srcs/parsing/expansions/expand_token.c +++ b/srcs/parsing/expansions/expand_token.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/11 21:04:41 by lperrey ### ########.fr */ +/* Updated: 2021/11/26 21:54:42 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,13 +14,6 @@ t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; - static t_list *ret_parameter_expansion(char *content, int *i); t_list *expand_token(char *content) @@ -92,7 +85,7 @@ static t_list *ret_parameter_expansion(char *content, int *i) if (content[*i] == '?') { (*i)++; - expand->content = ft_itoa(g_all->last_exit_status); + expand->content = ft_itoa(get_last_exit_status()); return (ft_retp_free(expand, tmp, free)); } else if (content[*i] != '_' && !ft_isalpha(content[*i])) diff --git a/srcs/parsing/expansions/ft_split_quotes.c b/srcs/parsing/expansions/ft_split_quotes.c index 83ccb22..8caf895 100644 --- a/srcs/parsing/expansions/ft_split_quotes.c +++ b/srcs/parsing/expansions/ft_split_quotes.c @@ -6,19 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/13 07:08:40 by lperrey #+# #+# */ -/* Updated: 2021/11/13 22:35:34 by lperrey ### ########.fr */ +/* Updated: 2021/11/26 21:27:10 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; - static size_t count_word(char const *s, char c); static char **alloc_words(char const *s, char c, char **str_arr, size_t words_count); diff --git a/srcs/parsing/expansions/ft_strdup_quotes.c b/srcs/parsing/expansions/ft_strdup_quotes.c index 1b4525f..65d04fb 100644 --- a/srcs/parsing/expansions/ft_strdup_quotes.c +++ b/srcs/parsing/expansions/ft_strdup_quotes.c @@ -6,18 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/13 04:35:06 by lperrey #+# #+# */ -/* Updated: 2021/11/14 06:01:45 by lperrey ### ########.fr */ +/* Updated: 2021/11/26 21:27:05 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; static int quote_state_change(int *quote_state, const char *s); /* Duplicate a string minus the quoting characters ['] and ["]*/ diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index 90db9a9..fa0eca5 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/07 04:33:04 by lperrey ### ########.fr */ +/* Updated: 2021/11/30 13:46:46 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -55,8 +55,7 @@ static t_token *insert_tokens(t_token *t, t_token *insert_lst) t_token *insert_lst_last; t->id = 0; - free(t->content); - t->content = NULL; // TODO : free_null() + ft_free_null(&t->content); if (!insert_lst) return (t); diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index a802bee..dfc9eb9 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,19 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/16 03:45:15 by lperrey ### ########.fr */ +/* Updated: 2021/11/26 21:05:01 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; - t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); t_list *expand_token(char *content); char *rejoin_after_expand(t_list *expand_lst); diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 1238543..a8f0f86 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,19 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/18 22:35:07 by hulamy ### ########.fr */ +/* Updated: 2021/11/29 12:28:07 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -// HUGO WIP -void handle_path(t_cmd **cmd_arr, char **envp); -void find_path(char **argv, char **envp); -int handle_builtin(t_cmd *cmd); -int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)); -// HUGO WIP - void save_redirections_words(t_token *t) { while (t) @@ -33,25 +26,25 @@ void save_redirections_words(t_token *t) } } -void print_cmd_array(t_cmd **cmd_arr) +void print_pipeline(t_cmd **pipeline) { int i; i = 0; - while (cmd_arr[i]) + while (pipeline[i]) { - printf("CMD %i, fd_in=%i, fd_out=%i\n", i, cmd_arr[i]->fd_in, cmd_arr[i]->fd_out); + 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(cmd_arr[i]->argv, "|\n |"); + print_matrix(pipeline[i]->argv, "|\n |"); i++; - if (cmd_arr[i]) + if (pipeline[i]) ft_putstr_fd("----------------\n", 1); } } t_cmd **parsing(t_token *token_list) { - t_cmd **cmd_arr; + t_cmd **pipeline; if (!valid_syntax(token_list)) return (NULL); @@ -74,20 +67,20 @@ t_cmd **parsing(t_token *token_list) //ft_lstprint((t_list *)token_list, 1); // Struct CMD alloc - cmd_arr = cmd_array_alloc(1 + count_pipes(token_list)); - if (!cmd_arr) + pipeline = pipeline_alloc(1 + count_pipes(token_list)); + if (!pipeline) return (NULL); // 2.9.1 - 3) Redirection - if (!redirections(token_list, cmd_arr)) - return (ft_retp_free(NULL, &cmd_arr, (t_free_f)free_pipeline)); + if (!redirections(token_list, pipeline)) + return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); // Struct CMD fill - if (!cmd_array_fill_argv(token_list, cmd_arr)) - return (ft_retp_free(NULL, &cmd_arr, (t_free_f)free_pipeline)); - print_cmd_array(cmd_arr); + if (!pipeline_fill_argv(token_list, pipeline)) + return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); + print_pipeline(pipeline); - return (cmd_arr); + return (pipeline); } /* ------------------------------------------------------- diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c index 37e8936..76dfa49 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/26 15:03:37 by hulamy ### ########.fr */ +/* Updated: 2021/12/02 15:32:56 by hulamy ### ########.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,11 +78,12 @@ 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; + g_switch_heredoc_sigint = 0; rl_event_hook = void_func_return_readline; //rl_signal_event_hook = void_func_return_readline; line_count = 0; @@ -90,11 +92,8 @@ static int here_doc_write(char *delimiter, int doc_fd) line_count++; line = NULL; line = readline("> "); - if (switch_heredoc_sigint == 1) - { - // todo : gerer le statut exit 130 - return (1); - } + if (g_switch_heredoc_sigint == 1) + return (set_last_exit_status(EXIT_SIGNAL + SIGINT)); if (!line) { // TODO : error print wrapper ft_putstr_fd("minishell: ", 2); @@ -103,20 +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); signal_action.sa_handler = SIG_IGN; sigaction(SIGINT, &signal_action, NULL); - return (1); + return (0); } /* diff --git a/srcs/parsing/redirections/redirections.c b/srcs/parsing/redirections/redirections.c index a8bcc55..5b3bea9 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/29 12:39:05 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,23 +17,23 @@ 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); -int redirections(t_token *t, t_cmd **cmd_arr) +int redirections(t_token *t, t_cmd **pipeline) { int i; i = 0; while (t) { - if (!cmd_arr[i]->error) + if (!pipeline[i]->error) { if (t->id == '<' || t->id == T_DLESS) { - if (!redirect_cmd_input(t, cmd_arr[i])) + if (!redirect_cmd_input(t, pipeline[i])) return (0); } else if (t->id == '>' || t->id == T_DGREAT) { - if (!redirect_cmd_output(t, cmd_arr[i])) + if (!redirect_cmd_output(t, pipeline[i])) return (0); } } @@ -60,14 +60,19 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) if (cmd->fd_in == -1) { ft_perror_io("open() ", t->next->content); // todo error - cmd->error = 42; // WIP error status + cmd->error = EXIT_REDIRECTION; } } else if (t->id == T_DLESS) { 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 = EXIT_REDIRECTION; + } + else if (cmd->fd_in > EXIT_SIGNAL) + return (0); } return (1); } @@ -93,7 +98,7 @@ static int redirect_cmd_output(t_token *t, t_cmd *cmd) if (cmd->fd_out == -1) { ft_perror_io("open() ", t->next->content); - cmd->error = 42; // WIP error status + cmd->error = EXIT_REDIRECTION; } return (1); } diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index d6ec04a..1a65c3c 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,12 +6,14 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/17 15:29:35 by hulamy ### ########.fr */ +/* Updated: 2021/12/01 14:45:04 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +static char *read_input(char *prompt, t_all *c); + void shell_loop(t_all *c) { char *line_input; @@ -21,32 +23,38 @@ void shell_loop(t_all *c) { if (line_input) free(line_input); - c->signal_behaviour.sa_handler = sigint_handler_interactive; - sigaction(SIGINT, &c->signal_behaviour, NULL); - line_input = readline(c->prompt); + line_input = read_input(c->prompt, c); if (line_input && *line_input) { - c->signal_behaviour.sa_handler = SIG_IGN; - sigaction(SIGINT, &c->signal_behaviour, NULL); add_history(line_input); - // Lexing - c->token_list = input_to_tokens(line_input); - free(line_input); - line_input = NULL; // TODO : free_null() + c->token_list = lexing(line_input); + ft_free_null(&line_input); if (!c->token_list) continue ; - // Parsing - c->cmd_arr = parsing(c->token_list); + c->pipeline = parsing(c->token_list); ft_lstclear((t_list **)&c->token_list, free); - if (!c->cmd_arr) + if (!c->pipeline) continue ; - // Exec Pipeline exec_cmd_line(c); } - else if (!line_input) - { - write(1, "exit\n", 5); - free_exit(c, c->last_exit_status); - } } } + +static char *read_input(char *prompt, t_all *c) +{ + char *line_input; + struct sigaction signal_behaviour; + + ft_bzero(&signal_behaviour, sizeof signal_behaviour); + signal_behaviour.sa_handler = sigint_handler_interactive; + sigaction(SIGINT, &signal_behaviour, NULL); + line_input = readline(prompt); + signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &signal_behaviour, NULL); + if (!line_input) + { + write(1, "exit\n", 5); + exit_free(c, get_last_exit_status()); + } + return (line_input); +} diff --git a/srcs/shell_script.c b/srcs/shell_script.c index 017d4aa..7790cfb 100644 --- a/srcs/shell_script.c +++ b/srcs/shell_script.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/26 23:47:44 by lperrey #+# #+# */ -/* Updated: 2021/10/30 15:01:13 by lperrey ### ########.fr */ +/* Updated: 2021/11/29 12:43:44 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,5 +15,5 @@ void shell_script(t_all *c) // WIP { ft_putstr_fd("Shell Script Placeholder\n", 1); - free_exit(c, EXIT_SUCCESS); + exit_free(c, EXIT_SUCCESS); } diff --git a/srcs/signals.c b/srcs/signals.c index e0a2371..61445b6 100644 --- a/srcs/signals.c +++ b/srcs/signals.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ -/* Updated: 2021/11/25 10:02:53 by hulamy ### ########.fr */ +/* Updated: 2021/11/26 21:45:22 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,7 +24,7 @@ void sigint_handler_interactive(int signum) void sigint_handler_heredoc(int signum) { (void)signum; - switch_heredoc_sigint = 1; + g_switch_heredoc_sigint = 1; rl_done = 1; // write (1, rl_line_buffer, ft_strlen(rl_line_buffer) + 1); // rl_line_buffer = "\004"; diff --git a/test_environ.c b/test_environ.c deleted file mode 100644 index 11bb493..0000000 --- a/test_environ.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include - -# define COL_GREEN "\001\e[0;32m\002" -# define COL_BROWN "\001\e[0;33m\002" -# define COL_PURPL "\001\e[0;35m\002" -# define _END "\001\e[0m\002" - -size_t ft_strlen(const char *s); -char *ft_strdup(const char *s); -size_t ft_2d_arrlen(void *ptr); -void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)); -void print_matrix(char **matrix, char *sep); -void *ft_resize_2d_arr(void *ptr, size_t add_nbr); -typedef void *(*t_dup_f)(void *); - - -int main(int argc, char *argv[], char *envp[]) -{ - extern char **environ; - int env_len; - char *print; - char *env_var; - - (void)argc; - (void)argv; - -print = COL_GREEN"\n[original ] :\n"_END; -write(1, print, strlen(print)); - env_len = ft_2d_arrlen(environ); - printf("\nenviron_len: %i\nenviron :\n", env_len); - print_matrix(environ, "\n"); - -print = COL_GREEN"\n[getenv] :\n"_END; -write(1, print, strlen(print)); - env_var = getenv("TESTT"); - if (env_var) - write(1, COL_PURPL"FOUND\n"_END, 21); - else - write(1, COL_PURPL"NOT FOUND\n"_END, 25); - -print = COL_BROWN"\n[resize ]...\n"_END; -write(1, print, strlen(print)); - environ = ft_resize_2d_arr(environ, 1); - -print = COL_BROWN"\n[add to ]...\n"_END; -write(1, print, strlen(print)); - environ[env_len] = "TESTT=testt"; - -print = COL_GREEN"\n[modified ] :\n"_END; -write(1, print, strlen(print)); - env_len = ft_2d_arrlen(environ); - printf("\nenviron_len: %i\nenviron :\n", env_len); - print_matrix(environ, "\n"); - -print = COL_GREEN"\n[getenv] :\n"_END; -write(1, print, strlen(print)); - env_var = getenv("TESTT"); - if (env_var) - write(1, COL_PURPL"FOUND\n"_END, 21); - else - write(1, COL_PURPL"NOT FOUND\n"_END, 25); - -printf("\n%s\n", env_var); - - return (0); -} - -void *ft_resize_2d_arr(void *ptr, size_t add_nbr) -{ - unsigned int i; - char **arr; - char **new_arr; - - new_arr = malloc((ft_2d_arrlen(ptr) + add_nbr + 1) * sizeof (void *)); - arr = (char **)ptr; - i = 0; - while (arr[i]) - { - new_arr[i] = arr[i]; - i++; - } -// free(arr); - return (new_arr); -} - -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); -} - -size_t ft_strlen(const char *s) -{ - size_t len; - - len = 0; - while (s[len] != '\0') - len++; - return (len); -} - -char *ft_strdup(const char *s) -{ - unsigned int i; - char *dup; - - dup = malloc(ft_strlen(s) + 1); - if (!dup) - return (NULL); - i = 0; - while (s[i]) - { - dup[i] = s[i]; - i++; - } - dup[i] = '\0'; - return (dup); -} - -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); -} - -void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) -{ - 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] = dup_func(arr[i]); - i++; - } - new_arr[i] = NULL; - return (new_arr); -} 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); +}