+++ /dev/null
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* execution.c :+: :+: :+: */
-/* +:+ +:+ +:+ */
-/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
-/* +#+#+#+#+#+ +#+ */
-/* Created: 2024/07/21 08:57:54 by ljiriste #+# #+# */
-<<<<<<< HEAD
-/* Updated: 2024/08/29 18:21:04 by ljiriste ### ########.fr */
-=======
-/* Updated: 2024/08/29 11:19:20 by lnikolov ### ########.fr */
->>>>>>> 42/trunk
-/* */
-/* ************************************************************************** */
-
-#include "execution.h"
-#include "builtins.h"
-#include "minishell_structs.h"
-#include "minishell.h"
-#include "libft.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/wait.h>
-
-int is_token_type(const t_parse_tree_node *node, const char *type)
-{
- return (!ft_strcmp(node->token.type, type));
-}
-
-void clear_old(t_vec *assignments, const char *new)
-{
- size_t i;
- char **assignment;
-
- i = assignments->size;
- while (i > 0)
- {
- --i;
- assignment = ft_vec_access(assignments, i);
- if (cmp_var_name(*assignment, new))
- continue ;
- ft_vec_erase(assignments, i, free);
- }
- return ;
-}
-
-int add_word(t_vec *exp_str, const char *word, const t_execution_env *env, int quote);
-
-int add_assignment(t_vec *assignments, const char *assignment, const t_execution_env *env)
-{
- t_vec advanced_copy;
- char *copy;
-
- if (ft_vec_init(&advanced_copy, sizeof(char)) != success)
- return (1);
- if (add_word(&advanced_copy, assignment, env, 0))
- return (1);
- *(char *)ft_vec_access(&advanced_copy, advanced_copy.size - 1) = '\0';
- copy = advanced_copy.vec;
- unquote_field(copy);
- 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, const t_execution_env *env)
-{
- size_t i;
- t_parse_tree_node *subnode;
-
- i = 0;
- while (i < prefix->children.size)
- {
- subnode = ft_vec_access(&prefix->children, i);
- if (is_token_type(subnode, "ASSIGNMENT_WORD"))
- {
- if (add_assignment(assignments, subnode->token.str, env))
- return (1);
- }
- else if (is_token_type(subnode, "cmd_prefix"))
- if (save_assignments_prefix(assignments, subnode, env))
- return (1);
- ++i;
- }
- return (0);
-}
-
-int save_assignments(t_vec *assignments, t_parse_tree_node *simple_command, const t_execution_env *env)
-{
- t_parse_tree_node *subnode;
-
- if (ft_vec_init(assignments, sizeof(char *)) != success)
- return (1);
- subnode = ft_vec_access(&simple_command->children, 0);
- if (is_token_type(subnode, "cmd_prefix"))
- return (save_assignments_prefix(assignments, subnode, env));
- return (0);
-}
-
-char *get_word(const t_parse_tree_node *parent)
-{
- char *res;
- const t_parse_tree_node *word = ft_vec_caccess(&parent->children, 0);
-
- res = ft_strdup(word->token.str);
- return (res);
-}
-
-int expand_filename(char **filename, const t_execution_env *env)
-{
- t_vec advanced_copy;
-
- if (ft_vec_init(&advanced_copy, sizeof(char)) != success)
- return (1);
- if (add_word(&advanced_copy, *filename, env, 0))
- {
- ft_vec_free(&advanced_copy, NULL);
- return (1);
- }
- free(*filename);
- *filename = advanced_copy.vec;
- filename[0][advanced_copy.size - 1] = '\0';
- unquote_field(*filename);
- return (0);
-}
-
-int add_redirection_file(t_vec *redirections, t_parse_tree_node *io_file, int fd, const t_execution_env *env)
-{
- 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);
- expand_filename(&filename, env);
- 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)
- {
- free(filename);
- return (1);
- }
- redir = (t_redirection){.from_to_fds[0] = fd, .from_to_fds[1] = sec_fd};
- }
- 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)
- {
- free(filename);
- return (1);
- }
- redir = (t_redirection){.from_to_fds[0] = fd, .from_to_fds[1] = sec_fd};
- }
- free(filename);
- return (ft_vec_append(redirections, &redir) != success);
-}
-
-int write_line_to_pipe(int pipe_fd, const char *line, const t_execution_env *env, int expand)
-{
- size_t i;
- char *var;
- const 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)
- ft_dprintf(pipe_fd, "%s", value);
- i += ft_strlen(var);
- free(var);
- }
- 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_strncmp(line, unquoted_delimiter, ft_strlen(line) - 1))
- {
- 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] = fd, .from_to_fds[1] = pipe_fds[0]};
- 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, env));
- 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);
-}
-
-static const char space = ' ';
-
-int add_word(t_vec *exp_str, const char *word, const t_execution_env *env, int quote)
-{
- size_t i;
- char *var;
- char *value;
- const char *const_val;
- int single_quoted;
- int error;
-
- error = 0;
- single_quoted = 0;
- i = 0;
- while (word[i])
- {
- if (word[i] == '\'')
- single_quoted = !single_quoted;
- if (word[i] == '$' && !single_quoted && (ft_isalnum(word[i + 1]) || word[i + 1] == '_' || word[i + 1] == '?'))
- {
- ++i;
- if (word[i] == '?')
- {
- ++i;
- value = ft_itoa(env->ret_val);
- }
- else
- {
- var = get_var_name(word + i);
- if (!var)
- return (1);
- i += ft_strlen(var);
- const_val = get_env_var_value(env, var);
- free(var);
- if (!const_val)
- continue;
- value = ft_strdup(const_val);
- }
- if (!value)
- return (1);
- if (quote)
- error = error || ft_vec_append(exp_str, "'") != success;
- error = error || ft_vec_append_range(exp_str, value, ft_strlen(value)) != success;
- if (quote)
- error = error || ft_vec_append(exp_str, "'") != success;
- free(value);
- if (error)
- return (1);
- }
- else
- if (ft_vec_append(exp_str, word + (i++)) != success)
- return (1);
- }
- if (ft_vec_append(exp_str, &space) != success)
- return (1);
- return (0);
-}
-
-int expand_cmd(t_vec *exp_str, const t_parse_tree_node *node, const t_execution_env *env)
-{
- size_t i;
- const t_parse_tree_node *subnode;
-
- i = 0;
- while (i < node->children.size)
- {
- subnode = ft_vec_caccess(&node->children, i);
- if (is_token_type(subnode, "cmd_suffix"))
- {
- if (expand_cmd(exp_str, subnode, env))
- return (1);
- }
- else if (is_token_type(subnode, "WORD"))
- if (add_word(exp_str, subnode->token.str, env, 0))
- return (1);
- ++i;
- }
- return (0);
-}
-
-size_t get_next_word_size(const char *str)
-{
- size_t n;
- char quote;
-
- quote = 0;
- n = 0;
- while (str[n])
- {
- if (str[n] == ' ' && !quote)
- break ;
- if ((str[n] == '"' || str[n] == '\''))
- {
- if (!quote)
- quote = str[n];
- else if (quote == str[n])
- quote = 0;
- }
- ++n;
- }
- return (n);
-}
-
-void unquote_field(char *field)
-{
- size_t i;
- char quote;
-
- quote = 0;
- i = 0;
- while (field && field[i])
- {
- if (field[i] == '"' || field[i] == '\'')
- {
- if (!quote)
- quote = field[i];
- else if (quote == field[i])
- quote = 0;
- else
- {
- ++i;
- continue ;
- }
- ft_memmove(field + i, field + i + 1, ft_strlen(field + i + 1) + 1);
- }
- else
- ++i;
- }
- return ;
-}
-
-void unquote(char **fields)
-{
- size_t i;
-
- i = 0;
- while (fields[i])
- {
- unquote_field(fields[i]);
- ++i;
- }
- return ;
-}
-
-static const void *nullptr = NULL;
-
-char **quoted_split(const char *str)
-{
- size_t i;
- size_t n;
- t_vec fields;
- char *new_str;
-
- if (ft_vec_init(&fields, sizeof(char *)) != success)
- return (NULL);
- i = 0;
- while (str[i])
- {
- while (str[i] == ' ')
- ++i;
- n = get_next_word_size(str + i);
- if (n == 0)
- break ;
- new_str = ft_strndup(str + i, n);
- if (!new_str)
- {
- ft_vec_free(&fields, free);
- return (NULL);
- }
- if (ft_vec_append(&fields, &new_str) != success)
- {
- ft_vec_free(&fields, free);
- free(new_str);
- return (NULL);
- }
- i += n;
- }
- if (ft_vec_append(&fields, &nullptr) != success)
- {
- ft_vec_free(&fields, free);
- return (NULL);
- }
- return (fields.vec);
-}
-
-static const char null_char = '\0';
-
-char **expand(t_parse_tree_node *simple_command, const t_execution_env *env)
-{
- size_t i;
- char **fields;
- t_vec expanded_str;
- t_parse_tree_node *subnode;
-
- ft_vec_init(&expanded_str, sizeof(char));
- ft_vec_reserve(&expanded_str, 64);
- i = 0;
- while (i < simple_command->children.size)
- {
- subnode = ft_vec_access(&simple_command->children, i);
- if (is_token_type(subnode, "cmd_name")
- || is_token_type(subnode, "cmd_word")
- || is_token_type(subnode, "cmd_suffix"))
- if (expand_cmd(&expanded_str, subnode, env))
- {
- ft_vec_free(&expanded_str, NULL);
- return (NULL);
- }
- ++i;
- }
- if (ft_vec_append(&expanded_str, &null_char) != success)
- {
- ft_vec_free(&expanded_str, NULL);
- return (NULL);
- }
- fields = quoted_split(expanded_str.vec);
- ft_vec_free(&expanded_str, NULL);
- unquote(fields);
- return (fields);
-}
-
-int assignments_to_env(const t_vec *assignments, t_execution_env *env)
-{
- size_t i;
- const char *var_line;
- char *var_name;
-
- i = 0;
- while (i < assignments->size)
- {
- var_line = *(char **)ft_vec_caccess(assignments, i);
- var_name = get_var_name(var_line);
- if (!var_name)
- return (1);
- if (set_env_var_value(env, var_name, var_line + ft_strlen(var_name) + 1))
- {
- free(var_name);
- return (1);
- }
- free(var_name);
- ++i;
- }
- return (0);
-}
-
-void free_split(char **fields)
-{
- size_t i;
-
- i = 0;
- while (fields[i])
- {
- free(fields[i]);
- ++i;
- }
- free(fields);
- return ;
-}
-
-int contains_path(const char *str)
-{
- return (ft_strchr(str, '/') != NULL);
-}
-
-int file_exists(const char *path)
-{
- return (!access(path, F_OK));
-}
-
-int is_contained_in_dir(const char *exe_name, const char *dir_name)
-{
- DIR *dir;
- struct dirent *dir_entry;
-
- dir = opendir(dir_name);
- if (!dir)
- return (0);
- dir_entry = readdir(dir);
- while (dir_entry)
- {
- if (!ft_strcmp(dir_entry->d_name, exe_name))
- {
- closedir(dir);
- return (1);
- }
- dir_entry = readdir(dir);
- }
- closedir(dir);
- return (0);
-}
-
-char *find_exe(const char *exe_name, const t_execution_env *env)
-{
- const char *path;
- char **paths;
- size_t i;
- char *res;
-
- path = get_env_var_value(env, "PATH");
- if (!path)
- return (NULL);
- paths = ft_split(path, ":");
- if (!paths)
- return (NULL);
- res = NULL;
- i = 0;
- while (paths[i] && !res)
- {
- if (is_contained_in_dir(exe_name, paths[i]))
- if (ft_strcat_alloc(&res, paths[i]))
- if (ft_strcat_alloc(&res, "/"))
- ft_strcat_alloc(&res, exe_name);
- ++i;
- }
- free_split(paths);
- return (res);
-}
-
-int dup_pipes(const t_execution_env *env)
-{
- if (dup2(env->stdin_fd, STDIN_FILENO) == -1)
- return (1);
- if (dup2(env->stdout_fd, STDOUT_FILENO) == -1)
- return (1);
- return (0);
-}
-
-void close_pipes(const t_execution_env *env)
-{
- close(env->stdin_fd);
- close(env->stdout_fd);
- return ;
-}
-
-int dup_redirections(__attribute__((unused)) const t_vec *redirections)
-{
- size_t i;
- const t_redirection *redir;
-
- i = 0;
- while (i < redirections->size)
- {
- redir = ft_vec_caccess(redirections, i);
- dup2(redir->from_to_fds[1], redir->from_to_fds[0]);
- close(redir->from_to_fds[1]);
- ++i;
- }
- return (0);
-}
-
-void close_redirections(const t_vec *redirections)
-{
- size_t i;
- const t_redirection *redir;
-
- i = 0;
- while (i < redirections->size)
- {
- redir = ft_vec_caccess(redirections, i);
- close(redir->from_to_fds[0]);
- ++i;
- }
- return ;
-}
-
-int add_exported(__attribute__((unused)) t_vec *assignments, __attribute__((unused)) const t_execution_env *env)
-{
- size_t i;
- char *var;
- const t_vec *exported;
-
- exported = &env->vars->exported;
- i = 0;
- while (i < exported->size)
- {
- var = ft_strdup(*(char *const *)ft_vec_caccess(exported, i));
- if (ft_vec_append(assignments, &var) != success) // Should exported be overwritten?
- return (1);
- ++i;
- }
- return (0);
-}
-
-int is_builtin(const char *str)
-{
- if (!ft_strcmp(str, "cd"))
- return (1);
- if (!ft_strcmp(str, "echo"))
- return (1);
- if (!ft_strcmp(str, "pwd"))
- return (1);
- if (!ft_strcmp(str, "env"))
- return (1);
- if (!ft_strcmp(str, "export"))
- return (1);
- if (!ft_strcmp(str, "unset"))
- return (1);
- if (!ft_strcmp(str, "exit"))
- return (1);
- return (0);
-}
-
-size_t count_fields(char **fields)
-{
- size_t i;
-
- i = 0;
- while (fields[i])
- ++i;
- return (i);
-}
-
-int save_std_filenos(int fds[3])
-{
- fds[0] = dup(STDIN_FILENO);
- if (fds[0] < 0)
- return (1);
- fds[1] = dup(STDOUT_FILENO);
- if (fds[1] < 0)
- {
- close(fds[0]);
- return (1);
- }
- fds[2] = dup(STDERR_FILENO);
- if (fds[2] < 0)
- {
- close(fds[0]);
- close(fds[1]);
- return (1);
- }
- return (0);
-}
-
-int restore_std_filenos(int fds[3])
-{
- if (dup2(fds[0], STDIN_FILENO) == -1)
- return (1);
- if (dup2(fds[1], STDOUT_FILENO) == -1)
- return (1);
- if (dup2(fds[2], STDERR_FILENO) == -1)
- return (1);
- close(fds[0]);
- close(fds[1]);
- close(fds[2]);
- return (0);
-}
-
-int ex_builtin(char **fields, __attribute__((unused)) t_vec *assignments, __attribute__((unused)) const t_vec *redirections, t_execution_env *env)
-{
- int fds[3];
-
- save_std_filenos(fds);
- dup_pipes(env);
- dup_redirections(redirections);
- if (!ft_strcmp(fields[0], "cd"))
- env->last_builtin_ret_val = cd(count_fields(fields), fields, env);
- else if (!ft_strcmp(fields[0], "echo"))
- env->last_builtin_ret_val = echo(count_fields(fields), fields);
- else if (!ft_strcmp(fields[0], "pwd"))
- env->last_builtin_ret_val = pwd();
- else if (!ft_strcmp(fields[0], "env"))
- env->last_builtin_ret_val = ft_env(count_fields(fields), env);
- else if (!ft_strcmp(fields[0], "export"))
- env->last_builtin_ret_val = export(count_fields(fields), fields, env);
- else if (!ft_strcmp(fields[0], "unset"))
- env->last_builtin_ret_val = unset(count_fields(fields), fields, env);
- else if (!ft_strcmp(fields[0], "exit"))
- env->last_builtin_ret_val = execute_exit(count_fields(fields), fields, env);
- else
- return (1);
- env->last_was_builtin = 1;
- close_redirections(redirections);
- close_pipes(env);
- restore_std_filenos(fds);
- return (0);
-}
-
-int ex_fields(char **fields, t_vec *assignments, const t_vec *redirections, t_execution_env *env)
-{
- pid_t pid;
- char *path;
-
- if (is_builtin(fields[0]))
- return (ex_builtin(fields, assignments, redirections, env));
- env->last_was_builtin = 0;
- path = NULL;
- if (contains_path(fields[0]) && file_exists(fields[0]))
- path = ft_strdup(fields[0]);
- else if (!contains_path(fields[0]))
- path = find_exe(fields[0], env);
- if (!path)
- return (1);
- pid = fork();
- if (pid == 0)
- {
- dup_pipes(env);
- dup_redirections(redirections);
- add_exported(assignments, env);
- ft_vec_append(assignments, nullptr);
- execve(path, fields, assignments->vec);
- exit(-1);
- }
- free(path);
- if (pid > 0)
- {
- if (ft_vec_append(&env->child_pids, &pid) != success)
- return (1);
- }
- else
- return (1);
- return (0);
-}
-
-void close_redirection(void *v_redir)
-{
- t_redirection *redir;
-
- redir = v_redir;
- close(redir->from_to_fds[1]);
- return ;
-}
-
-int ex_simple_command(t_parse_tree_node *simple_command, t_execution_env *env)
-{
- t_vec redirections;
- t_vec assignments;
- char **fields;
- int res;
-
- res = save_redirections(&redirections, simple_command, env);
- res = save_assignments(&assignments, simple_command, env) || res;
- fields = NULL;
- if (!res)
- fields = expand(simple_command, env);
- if (!fields || res)
- {
- ft_vec_free(&redirections, close_redirection);
- ft_vec_free(&assignments, free);
- return (1);
- }
- if (!*fields)
- {
- assignments_to_env(&assignments, env);
- ft_vec_free(&redirections, close_redirection);
- ft_vec_free(&assignments, free_str);
- free_split(fields);
- return (0);
- }
- res = ex_fields(fields, &assignments, &redirections, env);
- ft_vec_free(&redirections, close_redirection);
- ft_vec_free(&assignments, free_str);
- free_split(fields);
- return (res);
-}
-
-t_ft_stat v_strcopy(void *v_dest, const void *v_src)
-{
- char **dest;
- const char *const *src;
-
- dest = v_dest;
- src = v_src;
- if (!*src)
- {
- *dest = NULL;
- return (success);
- }
- *dest = ft_strdup(*src);
- if (!*dest)
- return (alloc_fail);
- return (success);
-}
-
-t_ft_stat v_copy_redir(void *v_dest, const void *v_src)
-{
- t_redirection *dest;
- const t_redirection *src;
-
- dest = v_dest;
- src = v_src;
- *dest = *src;
- return (success);
-}
-
-int ex_program(t_parse_tree_node *program, t_execution_env *env);
-
-int subshell(t_parse_tree_node *program, t_execution_env *env)
-{
- int res;
- int status;
- pid_t pid;
-
- pid = fork();
- if (pid == 0)
- {
- env->subshell = 1;
- res = ex_program(program, env);
- env->exit = 1;
- return (res);
- }
- else if (pid < 0)
- return (1);
- waitpid(pid, &status, 0);
- if (!WIFEXITED(status))
- return (1);
- env->ret_val = WEXITSTATUS(status);
- return (0);
-}
-
-int ex_command(t_parse_tree_node *command, t_execution_env *env)
-{
- t_parse_tree_node *comp_command;
-
- if (env->exit)
- return (0);
- if (is_token_type(ft_vec_caccess(&command->children, 0), "simple_command"))
- return (ex_simple_command(ft_vec_access(&command->children, 0), env));
- else
- {
- comp_command = ft_vec_access(&command->children, 0);
- return (subshell(ft_vec_access(&comp_command->children, 1), env));
- }
-}
-
-void killall(t_vec *child_pids, int sig_num)
-{
- pid_t child_pid;
- size_t i;
-
- i = 0;
- while (i < child_pids->size)
- {
- child_pid = *(pid_t *)ft_vec_access(child_pids, i);
- kill(child_pid, sig_num);
- ++i;
- }
- return ;
-}
-
-void wait_for_return(t_execution_env *env)
-{
- pid_t last_pid;
- int status;
-
- if (env->last_was_builtin)
- env->ret_val = env->last_builtin_ret_val;
- else
- {
- if (env->child_pids.size == 0)
- return ;
- last_pid = *(pid_t *)ft_vec_access(&env->child_pids, env->child_pids.size - 1);
- waitpid(last_pid, &status, 0);
- if (g_last_signal != 0)
- killall(&env->child_pids, g_last_signal);
- if (g_last_signal == 0)
- if (WIFEXITED(status))
- env->ret_val = WEXITSTATUS(status);
- }
- ft_vec_free(&env->child_pids, NULL);
- return ;
-}
-
-int ex_pipeline(t_parse_tree_node *pipeline, t_execution_env *env, int depth)
-{
- int pipe_fds[2];
-
- if (g_last_signal != 0)
- return (0);
- if (pipeline->children.size == 1)
- {
- if (ex_command(ft_vec_access(&pipeline->children, 0), env))
- return (1);
- }
- else
- {
- if (pipe(pipe_fds))
- return (1);
- ft_swap_int(&pipe_fds[1], &env->stdout_fd);
- ex_pipeline(ft_vec_access(&pipeline->children, 0), env, depth + 1);
- ft_swap_int(&pipe_fds[1], &env->stdout_fd);
- close(pipe_fds[1]);
- ft_swap_int(&pipe_fds[0], &env->stdin_fd);
- ex_command(ft_vec_access(&pipeline->children, 2), env);
- ft_swap_int(&pipe_fds[0], &env->stdin_fd);
- close(pipe_fds[0]);
- }
- if (depth == 0)
- wait_for_return(env);
- return (0);
-}
-
-int ex_program(t_parse_tree_node *program, t_execution_env *env)
-{
- if (program->children.size == 1)
- return (ex_pipeline(ft_vec_access(&program->children, 0), env, 0));
- if (ex_program(ft_vec_access(&program->children, 0), env))
- return (1);
- if (is_token_type(ft_vec_caccess(&program->children, 1), "AND_IF"))
- {
- if (env->ret_val == 0)
- return (ex_pipeline(ft_vec_access(&program->children, 2), env, 0));
- }
- else
- {
- if (env->ret_val != 0)
- return (ex_pipeline(ft_vec_access(&program->children, 2), env, 0));
- }
- return (0);
-}
-
-int execute(t_tree *parse_tree, t_execution_env *env)
-{
- int res;
-
- res = ex_program(parse_tree, env);
- if (g_last_signal != 0)
- {
- env->ret_val = 128 + g_last_signal;
- g_last_signal = 0;
- }
- return (res);
-}