From 1ac81bef263e0d2c6cad40aedf490f6d04bbbc47 Mon Sep 17 00:00:00 2001 From: Loic Deridder Date: Tue, 11 Feb 2025 11:07:57 +0100 Subject: [PATCH] heredocs + some leaks --- includes/minishell.h | 5 +- run_vg.sh | 2 +- srcs/execution/exec.c | 219 +++++++++++++++++++++++++++++-------- srcs/expander/expand_var.c | 4 +- srcs/main.c | 2 + srcs/parsing/heredoc.c | 64 ++++++++++- 6 files changed, 244 insertions(+), 52 deletions(-) diff --git a/includes/minishell.h b/includes/minishell.h index e4c718d..45634bb 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* minishell.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: nalebrun +#+ +:+ +#+ */ +/* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/27 11:25:25 by lderidde #+# #+# */ -/* Updated: 2025/02/07 17:22:16 by nalebrun ### ########.fr */ +/* Updated: 2025/02/11 08:41:31 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ typedef struct s_msh { int ex_code; t_ast_n *head; + int here_fd; char *input; int hist; char **env; diff --git a/run_vg.sh b/run_vg.sh index f5450c0..d4a1c2f 100755 --- a/run_vg.sh +++ b/run_vg.sh @@ -1 +1 @@ -make && valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all --trace-children=yes --suppressions=valgrind.supp -s ./minishell +make && valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all --suppressions=valgrind.supp -s ./minishell diff --git a/srcs/execution/exec.c b/srcs/execution/exec.c index 88eaa03..de5a064 100644 --- a/srcs/execution/exec.c +++ b/srcs/execution/exec.c @@ -6,7 +6,7 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/27 11:22:33 by lderidde #+# #+# */ -/* Updated: 2025/02/10 10:31:33 by lderidde ### ########.fr */ +/* Updated: 2025/02/11 11:06:48 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,13 +14,6 @@ #include #include #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include void handle_file(t_ast_n *node, int check, int i) { @@ -43,49 +36,181 @@ void handle_file(t_ast_n *node, int check, int i) node->_stdout = fd; } +static int is_validchar(char c) +{ + if (ft_isalnum(c) || c == '_') + return (1); + return (0); +} + +static int get_var_len(char *str, t_ast_n *node, int *j) +{ + int len; + int ret; + char *var; + + len = *j + 1; + while (str[len] && is_validchar(str[len])) + len++; + var = ft_substr(str, *j + 1, (size_t)len - (*j + 1)); + *j = len; + ret = ft_strlen(get_var_value(var, node->msh->env)); + ft_free(&var); + return (ret - (len - (*j + 1))); +} + +int get_dup_len(char *str, t_ast_n *node) +{ + int i; + int len; + + i = 0; + len = ft_strlen(str); + while (str[i]) + { + if (str[i] == '$') + { + len += get_var_len(str, node, &i); + i--; + } + i++; + } + return (len); +} + +static int valid_next(char c) +{ + if (c != '\0' && is_validchar(c)) + return (1); + return (0); +} + +static char *extract_env(char *str, char **envp) +{ + int i; + char *var; + char *tmp; + + i = 1; + while (str[i] && is_validchar(str[i])) + i++; + if (i > 1) + tmp = ft_substr(str, 1, i - 1); + var = get_var_value(tmp, envp); + ft_free(&tmp); + return (var); +} + +void expander_here(char **str, t_ast_n *node) +{ + char *new; + int i; + int j; + int len; + + i = -1; + len = get_dup_len(*str, node); + new = ft_calloc(len + 1, sizeof(char)); + if (!new) + return ; + j = 0; + while ((*str)[j] && ++i < len) + { + if ((*str)[j] != '$') + new[i] = (*str)[j++]; + else if ((*str)[j] == '$' && valid_next((*str)[j + 1])) + { + ft_strlcat(new, extract_env(&((*str)[j]), node->msh->env), -1); + i = ft_strlen(new) - 1; + while ((*str)[++j] && is_validchar((*str)[j])) + continue ; + } + } + ft_free(str); + *str = new; +} + +void here_remove_quote(t_ast_n *node, int j, char c) +{ + char *new; + int i; + int k; + int len; + + i = 0; + k = 0; + len = ft_strlen(node->files[j]); + new = ft_calloc(len - 1, sizeof(char)); + while (i < len - 2) + { + if ((&(node->files[j][k]) == ft_strchr(node->files[j], c)) || + (&(node->files[j][k]) == ft_strrchr(node->files[j], c))) + { + k++; + } + else + new[i++] = node->files[j][k++]; + } + ft_free(&node->files[j]); + node->files[j] = new; +} + +int ifhere_remove_quote(t_ast_n *node, int j) +{ + char c; + int ret; + + ret = 0; + if (!ft_strchr(node->files[j], '\'') && !ft_strchr(node->files[j], '\"')) + c = 0; + else if (!ft_strchr(node->files[j], '\"')) + c = '\''; + else if (!ft_strchr(node->files[j], '\'')) + c = '\"'; + else if (ft_strchr(node->files[j], '\'') < ft_strchr(node->files[j], '\"')) + c = '\''; + else + c = '\"'; + if (c && (ft_strchr(node->files[j], c) != ft_strrchr(node->files[j], c))) + here_remove_quote(node, j, c); + if (c) + ret = 1; + return (ret); +} + void read_input(t_ast_n *node, int j) { - char buf[100000]; - char c; - int r; - int i; + char *str; + int len; + int check; - r = 0; - i = 0; - ft_fprintf(2, "heredoc> "); - r = read(0, &c, 1); - while (r && c != '\n' && c != '\0') + check = ifhere_remove_quote(node, j); + len = ft_strlen(node->files[j]); + str = get_next_line(node->msh->here_fd); + while (str && ft_strncmp(str, node->files[j], len) != 0) { - if (c != '\n' && c != '\0') - buf[i++] = c; - r = read(STDIN_FILENO, &c, 1); + if (!check) + expander_here(&str, node); + write(1, str, ft_strlen(str)); + ft_free(&str); + str = get_next_line(node->msh->here_fd); } - buf[i] = '\0'; - if (ft_strncmp(buf, node->files[j], ft_strlen(node->files[j])) == 0) - { - close(node->fds[1]); - exit(EXIT_SUCCESS); - } - buf[i++] = '\n'; - buf[i] = '\0'; - ft_fprintf(node->fds[1], "%s", buf); + ft_free(&str); } void here_doc(t_ast_n *node, int i) { pid_t pid; - int fd; pipe(node->fds); pid = fork(); if (pid == 0) { - fd = open("/dev/tty", O_RDONLY); - dup2(fd, STDIN_FILENO); - close(fd); + dup2(node->fds[1], STDOUT_FILENO); close(node->fds[0]); - while (1) - read_input(node, i); + close(node->fds[1]); + read_input(node, i); + exit(EXIT_SUCCESS); } else if (pid > 0) { @@ -119,8 +244,8 @@ void handle_redir(t_ast_n *node) handle_file(node, 2, i); else if (node->redir[i] == _RED_DR) handle_file(node, 3, i); - // else if (node->redir[i] == _RED_DL) - // here_doc(node, i); + else if (node->redir[i] == _RED_DL) + here_doc(node, i); if (node->redir[i] == _RED_L) { dup2(node->_stdin, STDIN_FILENO); @@ -226,10 +351,10 @@ char *find_path(char *cmd, char **env) return (NULL); } -void return_error(char *arg, char *msg, int code) +void return_error(char *arg, char *msg, int code, t_ast_n *node) { ft_fprintf(2, "%s: %s\n", arg, msg); - free(arg); + free_child(node->msh); exit(code); } @@ -240,13 +365,16 @@ int exec(t_ast_n *node) expand_node(node); path = find_path(node->cmd, node->msh->env); if (!path) - return_error(node->cmd, "command not found", 127); + return_error(node->cmd, "command not found", 127, node); if (access(path, X_OK) != 0) - return_error(path, "Permission denied", 126); - execve(path, node->args, node->msh->env); - free(path); - perror("execve"); - exit(1); + return_error(path, "Permission denied", 126, node); + if (execve(path, node->args, node->msh->env) == -1) + { + free_child(node->msh); + perror("execve"); + exit(1); + } + return (0); } int exec_scmd(t_ast_n *node) @@ -433,7 +561,6 @@ int exec_subsh(t_ast_n *node) { handle_redir(node->parent); ret = execute_shcommand(node); - // reset_redir(node->parent); free_child(node->msh); exit(ret); } diff --git a/srcs/expander/expand_var.c b/srcs/expander/expand_var.c index 5bfab95..0679417 100644 --- a/srcs/expander/expand_var.c +++ b/srcs/expander/expand_var.c @@ -6,7 +6,7 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/07 12:58:25 by lderidde #+# #+# */ -/* Updated: 2025/02/10 09:12:39 by lderidde ### ########.fr */ +/* Updated: 2025/02/08 10:53:48 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ @@ -70,7 +70,7 @@ static int get_new_len(t_ast_n *node, int j) return (len); } -int valid_next(char c) +static int valid_next(char c) { if (c != '\0' && is_validchar(c)) return (1); diff --git a/srcs/main.c b/srcs/main.c index 2760dc8..ad2d0c5 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -56,7 +56,9 @@ static void interpret_cmd(char **input, t_msh *msh) ft_free(input); return ; } + msh->here_fd = open(".heredoc", O_RDONLY); msh->ex_code = execute_command(msh->head); + close(msh->here_fd); unlink(".heredoc"); free_ast(msh->head); msh->head = NULL; diff --git a/srcs/parsing/heredoc.c b/srcs/parsing/heredoc.c index 1e5b369..7f99e81 100644 --- a/srcs/parsing/heredoc.c +++ b/srcs/parsing/heredoc.c @@ -1,5 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lderidde +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/11 09:01:14 by lderidde #+# #+# */ +/* Updated: 2025/02/11 10:45:08 by lderidde ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "../../includes/minishell.h" +static void remove_quote(char **str, char c) +{ + char *new; + int i; + int k; + int len; + + i = 0; + k = 0; + len = ft_strlen(*str); + new = ft_calloc(len - 1, sizeof(char)); + while (i < len - 2) + { + if ((&((*str)[k]) == ft_strchr(*str, c)) || + (&((*str)[k]) == ft_strrchr(*str, c))) + { + k++; + } + else + new[i++] = (*str)[k++]; + } + ft_free(str); + *str = new; +} + +static int ifremove_quote(char **str) +{ + char c; + int ret; + + ret = 0; + if (!ft_strchr(*str, '\'') && !ft_strchr(*str, '\"')) + c = 0; + else if (!ft_strchr(*str, '\"')) + c = '\''; + else if (!ft_strchr(*str, '\'')) + c = '\"'; + else if (ft_strchr(*str, '\'') < ft_strchr(*str, '\"')) + c = '\''; + else + c = '\"'; + if (c && (ft_strchr(*str, c) != ft_strrchr(*str, c))) + remove_quote(str, c); + if (c) + ret = 1; + return (ret); +} + void read_hereinput(char *limiter) { char buf[100000]; @@ -14,6 +74,7 @@ void read_hereinput(char *limiter) if (r == 0) { ft_fprintf (2, "\n"); + ft_fprintf (1, "%s\n", limiter); exit(EXIT_SUCCESS); } while (r && c != '\n' && c != '\0') @@ -25,7 +86,7 @@ void read_hereinput(char *limiter) buf[i] = '\0'; if (ft_strncmp(buf, limiter, ft_strlen(limiter)) == 0) { - ft_fprintf(1, "%s", buf); + ft_fprintf(1, "%s\n", buf); exit(EXIT_SUCCESS); } buf[i++] = '\n'; @@ -42,6 +103,7 @@ void parse_heredoc(char *limiter) pid = fork(); if (pid == 0) { + ifremove_quote(&limiter); dup2(fd, STDOUT_FILENO); close (fd); while (1)