From 2c5247fb6a12bb163fadc0824baefea16aec3469 Mon Sep 17 00:00:00 2001 From: narnaud Date: Wed, 4 May 2022 21:12:27 +0200 Subject: [PATCH] -fixes: no more doubles signals, -new: added return messages (signals), generalized cmds struct use and included env in --- README.md | 7 ------- built-in.c | 33 +++++++++++++++------------------ caller.c | 40 ++++++++++++++++++++-------------------- env.c | 25 ++++++++++++------------- lexer.c | 19 +++++++------------ minishell.c | 24 ++++++++++++------------ minishell.h | 39 ++++++++++++++++++--------------------- parser.c | 20 ++++++++++---------- utils.c | 22 ++++++++++++++++++---- 9 files changed, 112 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index b108159..45ff735 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,10 @@ ## TODO : - free stack, -- handle environment, - finish built-ins, -- handle multiples heredocs, -- better env management -- j'ai oubliƩ ><' -- ... ? ## Notes : ## Issues : - cat | cat | ls crash on linux ? -- segfault on echo $PATH (g_env bad restaured) -- diff --git a/built-in.c b/built-in.c index 37f19d1..683aa63 100755 --- a/built-in.c +++ b/built-in.c @@ -12,22 +12,19 @@ #include "minishell.h" -int ft_echo(char *argv[]) +int ft_echo(t_command *cmd) { int no_nl; - no_nl = 0; - if (argv[1]) + if (*(++cmd->argv)) { - argv++; - if (ft_strncmp(*argv, "-n", 3) == 0 && argv++) + if (ft_strncmp(*(cmd->argv), "-n", 3) == 0 && cmd->argv++) no_nl = 1; - while (*argv) + while (*(cmd->argv)) { - ft_putstr_fd(*argv, 1); - argv++; - if (*argv) + ft_putstr_fd(*(cmd->argv), 1); + if (*(++cmd->argv)) ft_putstr_fd(" ", 1); } } @@ -36,11 +33,11 @@ int ft_echo(char *argv[]) return (0); } -int ft_pwd(char **argv) +int ft_pwd(t_command *cmd) { char *dir; - (void)argv; + (void)cmd; dir = ft_calloc(PATHS_MAX_SIZE, sizeof(char)); getcwd(dir, PATHS_MAX_SIZE); ft_putstr_fd(dir, 1); @@ -49,21 +46,21 @@ int ft_pwd(char **argv) return (0); } -int ft_cd(char **argv) +int ft_cd(t_command *cmd) { - if (argv[1]) + if (cmd->argv[1]) { - if (access(argv[1], X_OK)) + if (access(cmd->argv[1], X_OK)) { - printf("Minishell: %s: %s: Permission denied\n", argv[0], argv[1]); + printf("Minishell: %s: %s: Permission denied\n", cmd->argv[0], cmd->argv[1]); return (0); } - else if (access(argv[1], F_OK)) + else if (access(cmd->argv[1], F_OK)) { - printf("Minishell: %s: %s: Not a directory\n", argv[0], argv[1]); + printf("Minishell: %s: %s: Not a directory\n", cmd->argv[0], cmd->argv[1]); return (0); } - chdir(argv[1]); + chdir(cmd->argv[1]); return (1); } else diff --git a/caller.c b/caller.c index 8289787..53fbede 100644 --- a/caller.c +++ b/caller.c @@ -12,21 +12,21 @@ #include "minishell.h" -int command_call(char *argv[]) +int command_call(t_command *cmd) { - if (ft_strncmp(argv[0], "echo", 5) == 0) - return (ft_echo(argv)); - else if (ft_strncmp(argv[0], "pwd", 4) == 0) - return (ft_pwd(argv)); - else if (ft_strncmp(argv[0], "cd", 3) == 0) - return (ft_cd(argv)); - else if (ft_strncmp(argv[0], "export", 7) == 0) - return (ft_export(argv)); - else if (ft_strncmp(argv[0], "unset", 6) == 0) - return (ft_unset(argv)); - else if (ft_strncmp(argv[0], "env", 4) == 0) - return (ft_env(argv)); - else if (ft_strncmp(argv[0], "exit", 5) == 0) + if (ft_strncmp(cmd->argv[0], "echo", 5) == 0) + return (ft_echo(cmd)); + else if (ft_strncmp(cmd->argv[0], "pwd", 4) == 0) + return (ft_pwd(cmd)); + else if (ft_strncmp(cmd->argv[0], "cd", 3) == 0) + return (ft_cd(cmd)); + else if (ft_strncmp(cmd->argv[0], "export", 7) == 0) + return (ft_export(cmd)); + else if (ft_strncmp(cmd->argv[0], "unset", 6) == 0) + return (ft_unset(cmd)); + else if (ft_strncmp(cmd->argv[0], "env", 4) == 0) + return (ft_env(cmd)); + else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0) return (close_minishell(0)); else { @@ -35,25 +35,25 @@ int command_call(char *argv[]) } } -void exe(char *argv[], char *const envp[]) +void exe(t_command *cmd) { char **path_dirs; char *path; size_t path_length; - if (ft_strchr(argv[0], '/')) - execve(argv[0], argv, envp); + if (ft_strchr(cmd->argv[0], '/')) + execve(cmd->argv[0], cmd->argv, *cmd->envp); else { path_dirs = ft_split(getenv("PATH"), ':'); while (path_dirs) { - path_length = ft_strlen(*path_dirs) + ft_strlen(argv[0]) + 2; + path_length = ft_strlen(*path_dirs) + ft_strlen(cmd->argv[0]) + 2; path = ft_calloc(path_length, sizeof(char)); ft_memcpy(path, *path_dirs, ft_strlen(*path_dirs)); ft_memcpy(path + ft_strlen(*path_dirs),"/", 1); - ft_memcpy(path + ft_strlen(*path_dirs) + 1, argv[0], ft_strlen(argv[0])); - execve(path, argv, envp); + ft_memcpy(path + ft_strlen(*path_dirs) + 1, cmd->argv[0], ft_strlen(cmd->argv[0])); + execve(path, cmd->argv, *cmd->envp); path_dirs++; } } diff --git a/env.c b/env.c index 8a07016..31d75d8 100755 --- a/env.c +++ b/env.c @@ -12,9 +12,9 @@ #include "minishell.h" -int ft_unset(char **argv) +int ft_unset(t_command *cmd) { - if (!argv[1]) + if (!cmd->argv[1]) { //read(input_fd, PIPE_MAX_SIZE); return (1); @@ -22,15 +22,14 @@ int ft_unset(char **argv) return (0); } -int ft_env(char **argv) +int ft_env(t_command *cmd) { - (void)argv; int i; i = 0; - while (g_env[i]) + while ((*cmd->envp)[i]) { - printf("%s\n", g_env[i]); + printf("%s\n", (*cmd->envp)[i]); i++; } return (0); @@ -51,31 +50,31 @@ int is_valid_identifier(char *ident) return (0); } -int ft_export(char **argv) +int ft_export(t_command *cmd) { char **new; char **env; int i; i = 0; - new = ft_split(argv[1], '='); + new = ft_split(cmd->argv[1], '='); if (!is_valid_identifier(new[0])) { printf ("export: not an identifier: %s\n", new[0]); return (0); } - while (g_env[i]) + while ((*cmd->envp)[i]) { - env = ft_split(g_env[i], '='); + env = ft_split((*cmd->envp)[i], '='); if (!ft_strncmp(new[0], env[0], ft_strlen(new[0]) + 1)) { - g_env[i] = argv[1]; + (*cmd->envp)[i] = cmd->argv[1]; return (1); } i++; } - g_env[i] = argv[1]; - g_env[i + 1] = NULL; + (*cmd->envp)[i] = cmd->argv[1]; + (*cmd->envp)[i + 1] = NULL; return (1); } diff --git a/lexer.c b/lexer.c index 0e25dbb..cc000c5 100644 --- a/lexer.c +++ b/lexer.c @@ -88,27 +88,22 @@ int check_register(t_lexer *lex, char **line, char *tmp) int replace_var(char **line, char *tmp, int tmp_i) { - char **env; + int len; int i; char *var_name; + char *value; + // TODO : free split and var_name i = 1; - env = NULL; while (ft_isalpha((*line)[i]) || ft_isdigit((*line)[i]) || (*line)[i] == '_') i++; var_name = ft_substr(*line, 1, i - 1); + value = getenv(var_name); + len = ft_strlen(value); i = 0; - while (g_env[i]) - { - env = ft_split(g_env[i], '='); - if (!ft_strncmp(var_name, env[0], ft_strlen(var_name) + 1)) - break ; - i++; - } - i = 0; - while (env[1][i]) - tmp[tmp_i++] = env[1][i++]; + while (i < len) + tmp[tmp_i++] = value[i++]; tmp[tmp_i] = 0; *line += i; return (tmp_i); diff --git a/minishell.c b/minishell.c index a23e521..41116ff 100644 --- a/minishell.c +++ b/minishell.c @@ -12,8 +12,6 @@ # include "minishell.h" -char **g_env; - int caller(t_command *cmd) { pid_t pid; @@ -33,21 +31,25 @@ int caller(t_command *cmd) dup2(cmd->fd[0], STDIN_FILENO); if (cmd->fd[1]) dup2(cmd->fd[1], STDOUT_FILENO); - if (command_call(cmd->argv) == -1) - exe(cmd->argv, cmd->envp); + if (command_call(cmd) == -1) + exe(cmd); exit(1); } if (cmd->fd[1]) close(cmd->fd[1]); if (cmd->next) return (caller(cmd->next)); + waitpid(pid, &status, 0); + if (WIFEXITED(status) && WEXITSTATUS(status)) + write(1, "\n", 1); + if (WIFSIGNALED(status)) + printf("QUIT: %d\n", WTERMSIG(status)); if (cmd->fd[0]) close(cmd->fd[0]); - waitpid(pid, &status, 0); return (1); } -t_command *parser(t_token *tok, t_command *prev) +t_command *parser(char ***envp, t_token *tok, t_command *prev) { int i; t_command *cmd; @@ -60,6 +62,7 @@ t_command *parser(t_token *tok, t_command *prev) i = 0; cmd->argc = count_arguments(tok); cmd->argv = ft_calloc(cmd->argc + 1, sizeof(char *)); + cmd->envp = envp; while(tok && tok->type != PIPE) { if (tok->type) @@ -73,7 +76,7 @@ t_command *parser(t_token *tok, t_command *prev) cmd->argv[0], cmd->argc, cmd->fd[0], cmd->fd[1]); cmd->argv[i] = NULL; if (tok && tok->type == PIPE) - cmd->next = parser(tok->next, cmd); + cmd->next = parser(envp, tok->next, cmd); return (cmd); } @@ -107,14 +110,11 @@ t_token *lexer(char *line) return (lex->tokens); } -int main(int argc, char **argv, char**envp) +int main(int argc, char **argv, char **envp) { char *line; if (argc < 2) (void)argv; - g_env = envp; - signal(SIGINT, sigs_handler); - signal(SIGQUIT, sigs_handler); while (1) { termios(0); @@ -124,7 +124,7 @@ int main(int argc, char **argv, char**envp) halt(EXIT_FAILURE); if (is_empty(line)) continue ; - caller(parser(lexer(line), NULL)); + caller(parser(&envp, lexer(line), NULL)); add_history(line); } clear_history(); diff --git a/minishell.h b/minishell.h index f289669..2e5acb9 100644 --- a/minishell.h +++ b/minishell.h @@ -31,19 +31,28 @@ # include # include -extern char **g_env; +typedef struct s_command +{ + int argc; + char **argv; + char ***envp; + int fd[2]; + char *heredoc; + struct s_command *next; + struct s_command *prev; +} t_command; // ----------------------------------Utils.c -int ft_echo(char **argv); -int ft_pwd(char **argv); -int ft_cd(char **argv); +int ft_echo(t_command *cmd); +int ft_pwd(t_command *cmd); +int ft_cd(t_command *cmd); int close_minishell(int exit_code); // ----------------------------------Utils.c -int ft_unset(char **argv); -int ft_env(char **argv); +int ft_unset(t_command *cmd); +int ft_env(t_command *cmd); int is_valid_identifier(char *ident); -int ft_export(char **argv); +int ft_export(t_command *cmd); // ----------------------------------Utils.c @@ -53,20 +62,8 @@ void termios(int ctl); void sigs_handler(int sig_num); // ----------------------------------Caller.c - -typedef struct s_command -{ - int argc; - char **argv; - char **envp; - int fd[2]; - char *heredoc; - struct s_command *next; - struct s_command *prev; -} t_command; - -void exe(char *argv[], char *const envp[]); -int command_call(char *argv[]); +void exe(t_command *cmd); +int command_call(t_command *cmd); // ----------------------------------Parser.c diff --git a/parser.c b/parser.c index d64fe2a..54c8e1c 100644 --- a/parser.c +++ b/parser.c @@ -18,15 +18,15 @@ int push_heredoc(char *str) int pip[2]; pipe(pip); - while(1) - { - line = readline(">"); - if (!ft_strncmp(line, str, ft_strlen(str) + 1)) - break; - ft_putstr_fd(line, pip[1]); - write(pip[1], "\n", 1); - } - close(pip[1]); + while(1) + { + line = readline(">"); + if (!ft_strncmp(line, str, ft_strlen(str) + 1)) + break; + ft_putstr_fd(line, pip[1]); + write(pip[1], "\n", 1); + } + close(pip[1]); return (pip[0]); } @@ -37,7 +37,7 @@ size_t count_arguments(t_token *tok) ret = 0; while (tok && tok->type != PIPE) { - if (!tok->type) + if (!tok->type == WORD) ret++; tok = tok->next; } diff --git a/utils.c b/utils.c index 36ce084..f7a4615 100644 --- a/utils.c +++ b/utils.c @@ -23,6 +23,14 @@ int is_empty(char *line) return (1); } +void nothing(int sig_num) +{ + (void)sig_num; + //if (sig_num == SIGQUIT) + // write(1, "QUIT: 3\n", 8); + //else if (sig_num == SIGINT) + // write(1, "\n", 1); +} void termios(int ctl) { struct termios termios_p; @@ -34,18 +42,24 @@ void termios(int ctl) //termios_p.c_oflag &= CRDLY; //termios_p.c_lflag &= ICANON; if (ctl) - termios_p.c_lflag |= ECHOCTL; + { + termios_p.c_lflag |= ECHOCTL; + signal(SIGINT, nothing); + signal(SIGQUIT, nothing); + } else + { termios_p.c_lflag &= ~(ECHOCTL); + signal(SIGINT, sigs_handler); + signal(SIGQUIT, sigs_handler); + } termios_p.c_cc[VQUIT] = ctl * 28; tcsetattr(tty, TCSANOW, &termios_p); } void sigs_handler(int sig_num) { - if (sig_num == SIGQUIT) - printf("QUIT: 3\n"); - else if (sig_num == SIGINT) + if (sig_num == SIGINT) printf("\n"); rl_on_new_line(); rl_replace_line("", 0);