From 683bffa428e2ffc7c7b6cfd0819de823aa865bf0 Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Sun, 21 Jul 2024 17:44:24 +0200 Subject: [PATCH] Add the save_redirections function This function traverses the command prefix and suffix, opens all the files needed for redirection and saves the information to a t_vec. --- inc/minishell.h | 8 +- src/execution.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 280 insertions(+), 11 deletions(-) diff --git a/inc/minishell.h b/inc/minishell.h index a5446b5..0835940 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 13:22:57 by ljiriste #+# #+# */ -/* Updated: 2024/07/21 13:00:33 by ljiriste ### ########.fr */ +/* Updated: 2024/07/21 17:19:11 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,8 +23,8 @@ typedef struct s_vars typedef struct s_redirection { - int from_fd; - int to_fd; + int from_to_fds[2]; + size_t created; } t_redirection; typedef struct s_execution_env @@ -32,7 +32,7 @@ typedef struct s_execution_env int stdin_fd; int stdout_fd; int ret_val; - t_vars *env_vars; + t_vars *vars; t_vec redirections; } t_execution_env; diff --git a/src/execution.c b/src/execution.c index eb14d4b..004da7d 100644 --- a/src/execution.c +++ b/src/execution.c @@ -6,11 +6,16 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/21 08:57:54 by ljiriste #+# #+# */ -/* Updated: 2024/07/21 14:24:33 by ljiriste ### ########.fr */ +/* Updated: 2024/07/21 17:41:29 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +#include "libft.h" +#include +#include +#include +#include int cmp_var_name(const char *a, const char *b) { @@ -22,7 +27,7 @@ int cmp_var_name(const char *a, const char *b) eq_ptr = ft_strchr(b, '='); if (namelen != eq_ptr - b) return (1); - return (ft_strcmp(a, b, namelen)); + return (ft_strncmp(a, b, namelen)); } void clear_old(t_vec *assignments, const char *new) @@ -44,23 +49,20 @@ void clear_old(t_vec *assignments, const char *new) int add_assignment(t_vec *assignments, const char *assignment) { - size_t i; char *copy; - copy = ft_strdup(subnode->token.str); + copy = ft_strdup(assignment); if (!copy) return (1); clear_old(assignments, copy); if (ft_vec_append(assignments, ©) == success) return (0); - free(copy); return (1); } int save_assignments_prefix(t_vec *assignments, t_parse_tree_node *prefix) { size_t i; - char *assignment; t_parse_tree_node *subnode; i = 0; @@ -91,6 +93,273 @@ int save_assignments(t_vec *assignments, t_parse_tree_node *simple_command) return (0); } +char *get_word(const t_parse_tree_node *parent) +{ + char *res; + const t_parse_tree_node *word = ft_vec_caccess(&parent->children, 2); + + res = ft_strdup(word->token.str); + return (res); +} + +int add_redirection_file(t_vec *redirections, t_parse_tree_node *io_file, int fd) +{ + t_redirection redir; + const t_parse_tree_node *operator; + char *filename; + int sec_fd; + + filename = get_word(ft_vec_caccess(&io_file->children, 1)); + if (!filename) + return (1); + operator = ft_vec_caccess(&io_file->children, 0); + if (is_token_type(operator, "LESS")) + { + if (fd == -1) + fd = STDIN_FILENO; + sec_fd = open(filename, O_RDONLY); + if (sec_fd < 0) + return (1); + redir = (t_redirection){.from_to_fds[0] = sec_fd, .from_to_fds[1] = fd, .created = 0}; + } + else + { + if (fd < 0) + fd = STDOUT_FILENO; + if (is_token_type(operator, "GREAT")) + sec_fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + else + sec_fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + if (sec_fd == -1) + return (1); + redir = (t_redirection){.from_to_fds[0] = fd, .from_to_fds[1] = sec_fd, .created = 1}; + } + return (ft_vec_append(redirections, &redir) != success); +} + +char *get_var_name(const char *line) +{ + size_t i; + + i = 0; + while (line[i] && !ft_isspace(line[i])) + ++i; + return (ft_strndup(line, i)); +} + +char *get_var_value(const t_vec *vars, const char *var_name) +{ + size_t len; + size_t i; + const char *const *line; + + len = ft_strlen(var_name); + i = 0; + while (i < vars->size) + { + line = ft_vec_caccess(vars, i); + if (ft_strncmp(*line, var_name, len) && (*line)[len + 1] == '=') + return (ft_strdup(*line + len + 2)); + ++i; + } + return (ft_strdup("")); +} + +char *get_env_var_value(const t_execution_env *env, const char *var_name) +{ + char *res; + + res = get_var_value(&env->vars->other, var_name); + if (!res || res[0]) + return (res); + res = get_var_value(&env->vars->exported, var_name); + return (res); +} + +int write_line_to_pipe(int pipe_fd, const char *line, const t_execution_env *env, int expand) +{ + size_t i; + char *var; + char *value; + + i = 0; + while (line[i]) + { + if (line[i] != '$' || !expand) + { + ft_dprintf(pipe_fd, "%c", line[i]); + ++i; + continue ; + } + ++i; + var = get_var_name(line + i); + if (!var) + return (1); + value = get_env_var_value(env, var); + if (!value) + { + free(var); + return (1); + } + ft_dprintf(pipe_fd, "%s", value); + i += ft_strlen(var); + free(var); + free(value); + } + return (0);; +} + +char *unquote_delimiter(const char *str) +{ + size_t i; + char *res; + char quote_char; + + res = ft_strdup(str); + if (!res) + return (NULL); + i = 0; + quote_char = '\0'; + while (res[i]) + { + if ((res[i] == '"' || res[i] == '\'')) + { + if (!quote_char) + { + quote_char = res[i]; + ft_memmove(res + i, res + i + 1, ft_strlen(res + i + 1) + 1); + continue ; + } + else if (res[i] == quote_char) + { + quote_char = '\0'; + ft_memmove(res + i, res + i + 1, ft_strlen(res + i + 1) + 1); + continue ; + } + } + ++i; + } + return (res); +} + +int here_file_to_pipe(int pipe_fd, const char *delimiter, const t_execution_env *env) +{ + int expand; + char *line; + char *unquoted_delimiter; + + unquoted_delimiter = unquote_delimiter(delimiter); + if (!unquoted_delimiter) + return (1); + expand = !ft_strcmp(unquoted_delimiter, delimiter); + ft_printf("> "); + line = get_next_line(STDIN_FILENO); + while (line && ft_strcmp(line, unquoted_delimiter)) + { + if (write_line_to_pipe(pipe_fd, line, env, expand)) + { + get_next_line(-1); + free(line); + free(unquoted_delimiter); + return (1); + } + free(line); + ft_printf("> "); + line = get_next_line(STDIN_FILENO); + } + if (!line) + ft_printf("minishell: warning: here-document delimited by EOF instead of %s!\n", unquoted_delimiter); + get_next_line(-1); + free(line); + free(unquoted_delimiter); + return (0); +} + +int add_redirection_here(t_vec *redirections, t_parse_tree_node *io_here, int fd, const t_execution_env *env) +{ + char *delimiter; + int pipe_fds[2]; + int err; + t_redirection redir; + + delimiter = get_word(ft_vec_caccess(&io_here->children, 1)); + if (!delimiter) + return (1); + if (fd == -1) + fd = STDIN_FILENO; + if (pipe(pipe_fds)) + { + free(delimiter); + return (1); + } + err = here_file_to_pipe(pipe_fds[1], delimiter, env); + close(pipe_fds[1]); + free(delimiter); + if (err) + return (1); + redir = (t_redirection){.from_to_fds[0] = pipe_fds[0], .from_to_fds[1] = fd, .created = 1}; + return (ft_vec_append(redirections, &redir) != success); +} + +int add_redirection(t_vec *redirections, t_parse_tree_node *redirect, const t_execution_env *env) +{ + int fd; + t_parse_tree_node *subnode; + + fd = -1; + subnode = ft_vec_access(&redirect->children, 0); + if (redirect->children.size == 2) + { + fd = ft_atoi(subnode->token.str); + if (fd < 0) + fd = -2; + subnode = ft_vec_access(&redirect->children, 1); + } + if (is_token_type(subnode, "io_file")) + return (add_redirection_file(redirections, subnode, fd)); + else + return (add_redirection_here(redirections, subnode, fd, env)); +} + +int save_redirections_psfix(t_vec *redirections, t_parse_tree_node *node, const t_execution_env *env) +{ + size_t i; + t_parse_tree_node *subnode; + + i = 0; + while (i < node->children.size) + { + subnode = ft_vec_access(&node->children, i); + if (is_token_type(subnode, "io_redirect")) + { + if (add_redirection(redirections, subnode, env)) + return (1); + } + else if (is_token_type(subnode, "cmd_suffix") || is_token_type(subnode, "cmd_prefix")) + if (save_redirections_psfix(redirections, subnode, env)) + return (1); + ++i; + } + return (0); +} + +int save_redirections(t_vec *redirections, t_parse_tree_node *simple_command, const t_execution_env *env) +{ + t_parse_tree_node *subnode; + + if (ft_vec_init(redirections, sizeof(t_redirection)) != success) + return (1); + subnode = ft_vec_access(&simple_command->children, 0); + if (is_token_type(subnode, "cmd_prefix")) + if (save_redirections_psfix(redirections, subnode, env)) + return (1); + subnode = ft_vec_access(&simple_command->children, simple_command->children.size - 1); + if (is_token_type(subnode, "cmd_suffix")) + if (save_redirections_psfix(redirections, subnode, env)) + return (1); + return (0); +} + int ex_simple_command(t_parse_tree_node *simple_command, t_execution_env *env) { t_vec redirections; @@ -98,7 +367,7 @@ int ex_simple_command(t_parse_tree_node *simple_command, t_execution_env *env) char **fields; int res; - res = save_redirections(&redirections, simple_command); + res = save_redirections(&redirections, simple_command, env); res = res || save_assignments(&assignments, simple_command); if (!res) fields = expand(simple_command, env, &redirections, &assignments); -- 2.30.2