diff --git a/.gitignore b/.gitignore index a1a6a9c..8faecd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +Thumbs.db *.o *.swp *.out @@ -9,9 +10,11 @@ *.dSYM .vscode *.lnk +*.zip memo memo.txt minishell -*.zip arg_test osef_temp +env_var_test +memo_local diff --git a/.gitmodules b/.gitmodules index cb2e6ae..aee5a3e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libft"] path = libft url = git@bitbucket.org:LuckyLaszlo/libft.git +[submodule "minishell_tests"] + path = minishell_tests + url = git@bitbucket.org:LuckyLaszlo/minishell_tests.git diff --git a/Makefile b/Makefile index e596344..9a2a361 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ LIBS = -L $(LIBFT_D) -lft \ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a -SRCS = main.c init.c free.c generic.c error_wrappers.c \ +SRCS = main.c init.c retrieve_path.c free.c generic.c error_wrappers.c \ signals.c \ shell_loop.c shell_script.c \ lexing.c fill_token.c check_operators.c \ diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 8a95670..c1b39f3 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,14 +6,13 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/12/02 15:47:51 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:29:18 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_PROTOTYPES_H # define MINISHELL_PROTOTYPES_H -// variable globale int g_switch_heredoc_sigint; extern char **environ; @@ -24,7 +23,7 @@ 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, :) -int set_signals_handling(struct sigaction *signal_behaviour); +void set_signals_behaviour(void); // Shell modes void shell_loop(t_all *c); @@ -57,20 +56,22 @@ int simple_command_builtin(t_cmd *cmd, t_all *c); int builtin_cd(int argc, char *argv[], t_all *c); int builtin_pwd(int argc, char *argv[], t_all *c); int builtin_export(int argc, char *argv[], t_all *c); +int export_var(char *arg); int builtin_unset(int argc, char *argv[], t_all *c); int builtin_exit(int argc, char *argv[], t_all *c); int builtin_env(int argc, char *argv[], t_all *c); int builtin_echo(int argc, char *argv[], t_all *c); -int getenv_position(char **envp, char *name); // Free int exit_free(t_all *c, int exit_status); void free_pipeline(t_cmd **pipeline_ptr[]); void close_pipeline_fd(t_cmd *pipeline[]); +void close_stdio(void); typedef void (*t_free_f)(void *); // generic // Error wrappers -void shell_error(char *s1, char *s2); +int shell_error(char *s1, char *s2, char *s3, int ret_val); +int shell_perror(char *s1, char *s2, char *s3, int ret_val); // Generic char *ft_strjoinfree(char *s1, char *s2); @@ -89,6 +90,9 @@ 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); +int ft_is_posix_name(char *str); char **ft_split_quotes(char const *s, char c); char *ft_strdup_quotes(const char *s); diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 18f55ee..69b5f79 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -46,7 +46,7 @@ typedef struct s_all // struct termios interactive_termios; // int termios_changed; // struct sigaction ori_signal_behaviour; - struct sigaction signal_behaviour; +// struct sigaction signal_behaviour; } t_all; #endif diff --git a/libft b/libft index d58ee38..af88c1c 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit d58ee38bab0a9e0449d98efc9522b124c71632fd +Subproject commit af88c1ce23f0daa453c70cee0c61a30f71c2a622 diff --git a/minishell_tests b/minishell_tests new file mode 160000 index 0000000..7f638a0 --- /dev/null +++ b/minishell_tests @@ -0,0 +1 @@ +Subproject commit 7f638a0bf4e4a08150fb472b1b1e663c60df3038 diff --git a/srcs/builtins/cd.c b/srcs/builtins/cd.c index 1ceaafa..a1d5981 100644 --- a/srcs/builtins/cd.c +++ b/srcs/builtins/cd.c @@ -1,12 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/12/04 19:31:19 by lperrey #+# #+# */ +/* Updated: 2021/12/08 22:33:56 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "minishell.h" +#define CMD "builtin_cd" + +static int change_prompt(t_all *c); +static int change_env_pwd(void); + int builtin_cd(int argc, char *argv[], t_all *c) { - (void)argc; - chdir(argv[1]); - c->prompt = init_prompt(c->prompt_base); - if (!c->prompt) - return (ft_reti_perror(0, "init_prompt() error")); + char *dir; + + if (argc > 2) + return (shell_error("cd: ", "too many arguments", "", EXIT_FAILURE)); + else if (argc < 2 || ft_strncmp(argv[1], "~", 2) == 0) + { + dir = getenv("HOME"); + if (!dir) + return (shell_error("cd: ", "HOME not set", "", EXIT_FAILURE)); + } + else if (argc == 2) + dir = argv[1]; + if (chdir(dir) == -1) + return (shell_perror("cd: ", dir, ": ", EXIT_FAILURE)); + if (change_prompt(c) == -1) + return (ft_reti_perror(EXIT_FAILURE, CMD", change_prompt()")); + if (change_env_pwd() == -1) + return (ft_reti_perror(EXIT_FAILURE, CMD", change_env_pwd()")); + return (EXIT_SUCCESS); +} + +static int change_prompt(t_all *c) +{ + char *tmp; + + tmp = init_prompt(c->prompt_base); + if (!tmp) + return (-1); + free(c->prompt); + c->prompt = tmp; + return (0); +} + +static int change_env_pwd(void) +{ + char *tmp; + int ret; + + tmp = getenv("PWD"); + if (tmp) + { + tmp = ft_strjoin("OLDPWD=", tmp); + if (!tmp) + return (-1); + ret = export_var(tmp); + free(tmp); + if (ret == -1) + return (-1); + } + tmp = getcwd(NULL, 0); + if (!tmp) + return (-1); + tmp = ft_strjoinfree_s2("PWD=", tmp); + if (!tmp) + return (-1); + ret = export_var(tmp); + free(tmp); + if (ret == -1) + return (-1); return (0); } diff --git a/srcs/builtins/env.c b/srcs/builtins/env.c index 6642079..0e83f21 100644 --- a/srcs/builtins/env.c +++ b/srcs/builtins/env.c @@ -6,16 +6,17 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 05:01:26 by lperrey #+# #+# */ -/* Updated: 2021/11/27 11:18:55 by lperrey ### ########.fr */ +/* Updated: 2021/12/01 17:19:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int builtin_env(int argc, char *argv[], t_all *c) // WIP +int builtin_env(int argc, char *argv[], t_all *c) { (void)argc; (void)argv; + (void)c; ft_putendl_arr_fd(environ, 1); return (0); } diff --git a/srcs/builtins/exit.c b/srcs/builtins/exit.c index 7a726ea..1464d29 100644 --- a/srcs/builtins/exit.c +++ b/srcs/builtins/exit.c @@ -12,7 +12,7 @@ #include "minishell.h" -int builtin_exit(int argc, char *argv[], t_all *c) // WIP +int builtin_exit(int argc, char *argv[], t_all *c) { unsigned char status; int i; diff --git a/srcs/builtins/export.c b/srcs/builtins/export.c index 6e190b7..2d4e285 100644 --- a/srcs/builtins/export.c +++ b/srcs/builtins/export.c @@ -1,33 +1,94 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/12/03 13:36:54 by lperrey #+# #+# */ +/* Updated: 2021/12/06 03:19:30 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "minishell.h" -int getenv_position(char **envp, char *name) // TODO : virer arg envp et utiliser "extern **environ" à la place -{ - int i; +static int change_var_value(char *arg, char *var_name); - i = 0; - while (envp[i] && ft_strncmp(envp[i], name, ft_strlen(name))) - i++; - return (i); -} +#define ERR_ID 1 +#define ERR_ID_STR ": not a valid identifier" +#define CMD "builtin_export" int builtin_export(int argc, char *argv[], t_all *c) { - char **var; - int env_position; + int i; + int exit_value; + int ret; (void)argc; - (void)c; - if (!ft_strchr(argv[1], '=')) - return (0); - var = ft_split(argv[1], '='); - env_position = getenv_position(environ, var[0]); - 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)) // 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); + exit_value = EXIT_SUCCESS; + i = 1; + while (argv[i]) + { + ret = export_var(argv[i]); + if (ret == -1) + return (ft_reti_perror(EXIT_FAILURE, CMD", export_var()")); + else if (ret == ERR_ID) + exit_value = EXIT_FAILURE; + if (ft_strncmp(argv[i], "PATH=", 5) == 0) + c->path = retrieve_path(); + i++; + } + return (exit_value); } +// in complete shell, must mark arguments for export +// (Not implemented in minishell) +// arg == var_name[=value] +// return "-1" on alloc error +int export_var(char *arg) +{ + char **var_split; + int ret; + + ret = 0; + var_split = ft_split(arg, '='); + if (!var_split) + return (-1); + if (!ft_is_posix_name(var_split[0])) + { + shell_error("export: ", var_split[0], ERR_ID_STR, 0); + ft_free_2d_arr(var_split); + return (ERR_ID); + } + if (ft_strchr(arg, '=')) + ret = change_var_value(arg, var_split[0]); + ft_free_2d_arr(var_split); + return (ret); +} + +static int change_var_value(char *arg, char *var_name) +{ + int env_position; + char *tmp; + + env_position = ft_getenv_position(var_name); + if (environ[env_position] == NULL) + { + environ = ft_resize_2d_arr(environ, 1); + if (!environ) + return (ft_reti_perror(-1, CMD", ft_resize_2d_arr()")); + } + tmp = ft_strdup(arg); + if (!tmp) + return (ft_reti_perror(-1, CMD", ft_strdup()")); + free(environ[env_position]); + environ[env_position] = tmp; + return (EXIT_SUCCESS); +} + +/* +environment variables must be POSIX NAME : + 3.235 Name +https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html +#tag_03_235 +*/ diff --git a/srcs/builtins/pwd.c b/srcs/builtins/pwd.c index 7b4f630..981be6c 100644 --- a/srcs/builtins/pwd.c +++ b/srcs/builtins/pwd.c @@ -1,15 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pwd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/12/04 19:15:36 by lperrey #+# #+# */ +/* Updated: 2021/12/04 20:22:49 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "minishell.h" int builtin_pwd(int argc, char *argv[], t_all *c) { - char *pwd; + char *working_dir; (void)argc; (void)argv; (void)c; - pwd = getcwd(NULL, 0); - write(1, pwd, ft_strlen(pwd)); + working_dir = getcwd(NULL, 0); + if (!working_dir) + return (ft_reti_perror(EXIT_FAILURE, "builtin_pwd, getcwd()")); + write(1, working_dir, ft_strlen(working_dir)); write(1, "\n", 1); - return (0); + free(working_dir); + return (EXIT_SUCCESS); } diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c index 755c76f..474417c 100644 --- a/srcs/builtins/unset.c +++ b/srcs/builtins/unset.c @@ -1,24 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* unset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/12/05 17:05:05 by lperrey #+# #+# */ +/* Updated: 2021/12/05 18:14:28 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "minishell.h" +static int unset_env_var(char *arg); + int builtin_unset(int argc, char *argv[], t_all *c) { - int env_position; - int i; + int i; + int exit_value; (void)argc; (void)c; + exit_value = EXIT_SUCCESS; i = 1; while (argv[i]) { - env_position = getenv_position(environ, argv[i]); - free(environ[env_position]); - while (environ[env_position]) - { - environ[env_position] = environ[env_position + 1]; - env_position++; - } + if (unset_env_var(argv[i]) == EXIT_FAILURE) + exit_value = EXIT_FAILURE; i++; } - return (0); + return (exit_value); } + +static int unset_env_var(char *arg) +{ + int env_position; + + if (!ft_is_posix_name(arg)) + { + shell_error("unset: ", arg, ": not a valid identifier", 0); + return (EXIT_FAILURE); + } + env_position = ft_getenv_position(arg); + free(environ[env_position]); + while (environ[env_position]) + { + environ[env_position] = environ[env_position + 1]; + env_position++; + } + return (EXIT_SUCCESS); +} + +/* +environment variables must be POSIX NAME : + 3.235 Name +https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html +#tag_03_235 +*/ diff --git a/srcs/error_wrappers.c b/srcs/error_wrappers.c index df1d6f2..aef5775 100644 --- a/srcs/error_wrappers.c +++ b/srcs/error_wrappers.c @@ -6,13 +6,13 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/12/01 17:16:30 by lperrey #+# #+# */ -/* Updated: 2021/12/01 17:19:02 by lperrey ### ########.fr */ +/* Updated: 2021/12/05 16:26:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void shell_error(char *s1, char *s2) +int shell_error(char *s1, char *s2, char *s3, int ret_val) { char *prefix; @@ -22,5 +22,24 @@ void shell_error(char *s1, char *s2) write(STDERR_FILENO, s1, ft_strlen(s1)); if (s2) write(STDERR_FILENO, s2, ft_strlen(s2)); + if (s3) + write(STDERR_FILENO, s3, ft_strlen(s3)); write(STDERR_FILENO, "\n", 1); + return (ret_val); +} + +int shell_perror(char *s1, char *s2, char *s3, int ret_val) +{ + 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)); + if (s3) + write(STDERR_FILENO, s3, ft_strlen(s3)); + perror(NULL); + return (ret_val); } diff --git a/srcs/exec/find_access.c b/srcs/exec/find_access.c index fbe16e5..22d44a1 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/01 17:16:55 by lperrey ### ########.fr */ +/* Updated: 2021/12/05 16:20:55 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,7 +48,7 @@ int cmd_find_access(t_cmd *cmd, char *path[]) if (!cmd->path) { cmd->error = EXIT_CMD_NOT_FOUND; - shell_error(cmd->argv[0], ": command not found"); + shell_error(cmd->argv[0], ": ", "command not found", 0); } } return (1); diff --git a/srcs/exec/pipeline.c b/srcs/exec/pipeline.c index 6646d52..3a0354f 100644 --- a/srcs/exec/pipeline.c +++ b/srcs/exec/pipeline.c @@ -45,7 +45,7 @@ static int open_pipes(t_cmd *pipeline[]) else if (close(pipes[STDOUT_FILENO]) == -1) perror("close()"); - if (pipeline[i]->fd_in == STDIN_FILENO) + if (pipeline[i + 1]->fd_in == STDIN_FILENO) pipeline[i + 1]->fd_in = pipes[STDIN_FILENO]; else if (close(pipes[STDIN_FILENO]) == -1) diff --git a/srcs/exec/subshell_exec.c b/srcs/exec/subshell_exec.c index 273f9bf..1e1374d 100644 --- a/srcs/exec/subshell_exec.c +++ b/srcs/exec/subshell_exec.c @@ -14,13 +14,17 @@ int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) { + struct sigaction signal_behaviour; + cmd->pid = fork(); if (cmd->pid == -1) perror("fork()"); if (cmd->pid == 0) { - c->signal_behaviour.sa_handler = SIG_DFL; - sigaction(SIGINT, &c->signal_behaviour, NULL); + ft_bzero(&signal_behaviour, sizeof signal_behaviour); + signal_behaviour.sa_handler = SIG_DFL; + sigaction(SIGINT, &signal_behaviour, NULL); + sigaction(SIGQUIT, &signal_behaviour, NULL); if (cmd->fd_in != STDIN_FILENO) if (dup2(cmd->fd_in, STDIN_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); diff --git a/srcs/free.c b/srcs/free.c index 285350b..303a182 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -23,6 +23,7 @@ int exit_free(t_all *c, int exit_status) //if (c->termios_changed) // tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); rl_clear_history(); + close_stdio(); exit(exit_status); } @@ -70,3 +71,13 @@ void close_pipeline_fd(t_cmd *pipeline[]) i++; } } + +void close_stdio(void) +{ + if (close(STDIN_FILENO) == -1) + perror("close()"); + if (close(STDOUT_FILENO) == -1) + perror("close()"); + if (close(STDERR_FILENO) == -1) + perror("close()"); +} diff --git a/srcs/generic.c b/srcs/generic.c index 65d8a48..15ef502 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/12/02 15:49:33 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:28:48 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -218,3 +218,76 @@ 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/init.c b/srcs/init.c index 576e6ba..f4ed219 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/12/03 06:55:40 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:28:16 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ static char *init_prompt_base(void); static int init_readline_hook(void); +static int shlvl_init(void); int init(t_all *c) { @@ -26,34 +27,45 @@ int init(t_all *c) 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")); + return (ft_reti_perror(0, "ft_dup_2d_arr(environ)")); c->path = retrieve_path(); + if (!shlvl_init()) + return (ft_reti_perror(0, "shlvl_init()")); c->prompt_base = init_prompt_base(); if (!c->prompt_base) - return (ft_reti_perror(0, "init_prompt_base() error")); + return (ft_reti_perror(0, "init_prompt_base()")); c->prompt = init_prompt(c->prompt_base); if (!c->prompt) - return (ft_reti_perror(0, "init_prompt() error")); - set_signals_handling(&c->signal_behaviour); + return (ft_reti_perror(0, "init_prompt()")); + set_signals_behaviour(); return (1); } -// done : TODO : Un appel à builtin_export() modifiant $PATH doit aussi entrainer un appel à "c->path = retrieve_path()" -char **retrieve_path(void) +static int shlvl_init(void) { - char *path; - char **path_split; + char *tmp; + int ret; - path = getenv("PATH"); - if (!path) - return (ft_retp_print(NULL, "minishell: Warning, $PATH not set\n", 2)); - path_split = ft_split(path, ':'); - if (!path_split) - return (ft_retp_perror(NULL, "retrieve_path()")); - return (path_split); + tmp = getenv("SHLVL"); + if (tmp && ft_isdigit_str(tmp)) + { + tmp = ft_itoa(ft_atoi(tmp) + 1); + if (!tmp) + return (0); + tmp = ft_strjoinfree_s2("SHLVL=", tmp); + if (!tmp) + return (0); + ret = export_var(tmp); + free(tmp); + } + else + ret = export_var("SHLVL=1"); + if (ret == -1) + return (0); + return (1); } -static char *init_prompt_base(void) // WIP, error return TODO +static char *init_prompt_base(void) { char *prompt_base; char *tmp; @@ -64,21 +76,33 @@ static char *init_prompt_base(void) // WIP, error return TODO if (!tmp) tmp = U_DEFAULT_USER; prompt_base = ft_strjoin(TERM_LIGHT_GREEN, tmp); + if (!prompt_base) + return (NULL); prompt_base = ft_strjoinfree_s1(prompt_base, "@"); + if (!prompt_base) + return (NULL); tmp = getenv("NAME"); if (!tmp) tmp = U_DEFAULT_NAME; prompt_base = ft_strjoinfree_s1(prompt_base, tmp); + if (!prompt_base) + return (NULL); prompt_base = ft_strjoinfree_s1(prompt_base, TERM_RESET":"TERM_LIGHT_BLUE); + if (!prompt_base) + return (NULL); return (prompt_base); } -char *init_prompt(char *prompt_base) // WIP, error return TODO +char *init_prompt(char *prompt_base) { char *prompt; prompt = ft_strjoinfree_s2(prompt_base, getcwd(NULL, 0)); + if (!prompt) + return (NULL); prompt = ft_strjoinfree_s1(prompt, TERM_RESET U_PROMPT_END); + if (!prompt) + return (NULL); return (prompt); } diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c index 5914fb4..d3a2775 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/12/01 14:54:22 by lperrey ### ########.fr */ +/* Updated: 2021/12/05 17:11:31 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -63,6 +63,7 @@ static int tokenize_input(t_token *t, char *input, size_t input_len) } /* + 2.3 Token Recognition https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html #tag_18_03 */ diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c index d34e2a2..ae3e8ba 100644 --- a/srcs/parsing/expansions/expand_token.c +++ b/srcs/parsing/expansions/expand_token.c @@ -6,14 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/02 15:50:40 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:27:50 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -//t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); - static t_list *ret_parameter_expansion(char *content, int *i); t_list *expand_token(char *content) @@ -101,9 +99,12 @@ static t_list *ret_parameter_expansion(char *content, int *i) free(tmp); if (expand->content) expand->content = ft_strdup(expand->content); - else - expand->content = ft_calloc(1, 1); - if (!expand->content) - return (ft_retp_free(NULL, expand, free)); return (expand); } + +/* +environment variables must be POSIX NAME : + 3.235 Name +https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html +#tag_03_235 +*/ diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index 853b8e4..8a285f8 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -6,14 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/02 15:50:46 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:27:26 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -//t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); - static t_token *insert_tokens(t_token *t, t_token *insert_lst); int new_token_for_each_field(char **fields, t_token **t) @@ -27,21 +25,16 @@ int new_token_for_each_field(char **fields, t_token **t) i = 0; while (fields[i]) { - if (fields[i][0]) - { - insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(t_token), 0); - insert_lst = insert_lst->next; - if (!insert_lst) - {//todo wrap - perror("insert_token_for_each_field() error"); - ft_free_2d_arr(fields); - return ((int)ft_lstclear((t_list **)&head.next, NULL)); - } - insert_lst->content = fields[i]; - insert_lst->id = T_WORD; + insert_lst->next = ft_lstnew_generic(sizeof(t_token), 0); + insert_lst = insert_lst->next; + if (!insert_lst) + {//todo wrap + perror("insert_token_for_each_field() error"); + ft_free_2d_arr(fields); + return ((int)ft_lstclear((t_list **)&head.next, NULL)); } - else - free(fields[i]); + insert_lst->content = fields[i]; + insert_lst->id = T_WORD; i++; } free(fields); diff --git a/srcs/parsing/expansions/rejoin_after_expand.c b/srcs/parsing/expansions/rejoin_after_expand.c index c56c98b..917b921 100644 --- a/srcs/parsing/expansions/rejoin_after_expand.c +++ b/srcs/parsing/expansions/rejoin_after_expand.c @@ -18,12 +18,7 @@ char *rejoin_after_expand(t_list *expand_lst) char *result; head = expand_lst; - result = ft_calloc(1, 1); - if (!result) - {//todo wrap - perror("rejoin_after_expand() error"); - return (ft_lstclear(&head, free)); - } + result = NULL; while (expand_lst) { result = ft_strjoinfree_s1(result, expand_lst->content); diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index 0b20e98..58e58fe 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,13 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/12/02 15:46:31 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:27:01 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -//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); int new_token_for_each_field(char **fields, t_token **t); diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 5adbe76..6234c12 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/12/05 14:02:10 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:26:31 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -78,7 +78,7 @@ t_cmd **parsing(t_token *token_list) // Struct CMD fill if (!pipeline_fill_argv(token_list, pipeline)) return (ft_retp_free(NULL, &pipeline, (t_free_f)free_pipeline)); -// print_pipeline(pipeline); + //print_pipeline(pipeline); return (pipeline); } diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c index a8daf1d..31ec976 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/05 17:42:35 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:25:54 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,9 +25,6 @@ int here_doc(char *delimiter) and the here-document lines shall not be expanded. Otherwise, the delimiter shall be the word itself. */ // TODO : A voir si on fait les expansions de variables dans le here_doc. - // implementer une gestion des signaux pour here_doc (verifier comportement bash et doc POSIX). - // 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; @@ -101,7 +98,7 @@ 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 (0); } 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 ; diff --git a/srcs/parsing/redirections/redirections.c b/srcs/parsing/redirections/redirections.c index 210900a..1754daf 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/05 14:00:22 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:25:34 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ int redirections(t_token *t, t_cmd **pipeline) return (0); } } - else if (t->id == '|') + if (t->id == '|') i++; t = t->next; } @@ -72,7 +72,10 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) cmd->error = EXIT_REDIRECTION; } else if (cmd->fd_in > EXIT_SIGNAL) + { + cmd->fd_in = 0; return (0); + } } return (1); } diff --git a/srcs/retrieve_path.c b/srcs/retrieve_path.c new file mode 100644 index 0000000..27ee2d2 --- /dev/null +++ b/srcs/retrieve_path.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* retrieve_path.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ +/* Updated: 2021/12/08 06:27:23 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char **retrieve_path(void) +{ + char *path; + char **path_split; + + path = getenv("PATH"); + if (!path) + return (ft_retp_print(NULL, "minishell: Warning, $PATH not set\n", 2)); + path_split = ft_split(path, ':'); + if (!path_split) + return (ft_retp_perror(NULL, "retrieve_path()")); + return (path_split); +} diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 77b902a..12b6e93 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/12/05 14:15:18 by hulamy ### ########.fr */ +/* Updated: 2021/12/10 10:23:40 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ static char *read_input(char *prompt, t_all *c) sigaction(SIGINT, &signal_behaviour, NULL); if (!line_input) { - write(2, "exit\n", 5); + write(STDERR_FILENO, "exit\n", 5); exit_free(c, get_last_exit_status()); } return (line_input); diff --git a/srcs/signals.c b/srcs/signals.c index 61445b6..e21e689 100644 --- a/srcs/signals.c +++ b/srcs/signals.c @@ -14,33 +14,25 @@ void sigint_handler_interactive(int signum) { - (void)signum; write(1, "\n", 1); rl_on_new_line(); rl_replace_line("", 1); rl_redisplay(); + set_last_exit_status(EXIT_SIGNAL + signum); } void sigint_handler_heredoc(int signum) { (void)signum; - g_switch_heredoc_sigint = 1; rl_done = 1; -// write (1, rl_line_buffer, ft_strlen(rl_line_buffer) + 1); -// rl_line_buffer = "\004"; -// write(1, "\004", 1); -// rl_on_new_line(); -// rl_replace_line((char *)NULL, 1); -// rl_replace_line("\004", 1); -// rl_replace_line("", 1); -// rl_redisplay(); + g_switch_heredoc_sigint = 1; } -int set_signals_handling(struct sigaction *signal_behaviour) +void set_signals_behaviour(void) { - signal_behaviour->sa_handler = sigint_handler_interactive; - sigaction(SIGINT, signal_behaviour, NULL); - signal_behaviour->sa_handler = SIG_IGN; - sigaction(SIGQUIT, signal_behaviour, NULL); - return (1); + struct sigaction signal_behaviour; + + ft_bzero(&signal_behaviour, sizeof signal_behaviour); + signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &signal_behaviour, NULL); }