diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | include/env.h | 13 | ||||
| -rw-r--r-- | include/minishell.h | 10 | ||||
| -rw-r--r-- | src/env.c | 64 | ||||
| -rw-r--r-- | src/env_to_strlst.c | 58 | ||||
| -rw-r--r-- | src/execute_cmd.c | 76 | ||||
| -rw-r--r-- | src/get_cmd_path.c | 82 | ||||
| -rw-r--r-- | src/interpreter.c | 85 | ||||
| -rw-r--r-- | src/main.c | 11 | ||||
| -rw-r--r-- | src/repl.c | 7 |
10 files changed, 378 insertions, 31 deletions
@@ -13,7 +13,8 @@ HEADERS = -I include -I $(LIB_DIR)/libft VPATH := src SRC := main.c debug_tools.c init.c signal_handling.c repl.c new_token.c \ free_token.c new_node.c free_node.c tokenizer.c parser.c \ - parse_cmd.c collect_redirs.c print_ast.c + parse_cmd.c collect_redirs.c print_ast.c interpreter.c env.c \ + get_cmd_path.c env_to_strlst.c execute_cmd.c OBJ_DIR := _obj OBJ := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o)) diff --git a/include/env.h b/include/env.h index f3d3c75..a35bec3 100644 --- a/include/env.h +++ b/include/env.h @@ -3,13 +3,15 @@ /* ::: :::::::: */ /* env.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/08 16:53:39 by dkaiser #+# #+# */ -/* Updated: 2024/09/13 16:26:16 by dkaiser ### ########.fr */ +/* Updated: 2024/10/25 19:53:38 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ +#include "libft.h" + typedef struct s_env { char *name; @@ -17,8 +19,7 @@ typedef struct s_env struct s_env *next; } t_env; +void getenvlst(t_env **env, char **en); +void free_envlst(t_env **env); char *env_get(t_env *env, char *name); -void env_export(t_env *env, char *name, char *value); -void env_unset(t_env *env, char *name); -char **env_to_strlst(t_env *env); -t_env **env_from_strlst(char **lst); +char **env_to_strlst(t_env *env);
\ No newline at end of file diff --git a/include/minishell.h b/include/minishell.h index 6997b15..b2a3845 100644 --- a/include/minishell.h +++ b/include/minishell.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* minishell.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:49 by dkaiser #+# #+# */ -/* Updated: 2024/08/11 12:22:07 by dkaiser ### ########.fr */ +/* Updated: 2024/10/25 16:10:21 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,11 +29,15 @@ int init(void); int init_signal_handling(void); -void repl(const char *prompt); +void repl(const char *prompt, t_env **env); t_list *parse(t_token *tokens); t_node *parse_cmd(t_token *tokens); t_redirection *collect_redirs(t_token **tokens); void print_ast(t_node *ast); + +int eval(t_node *node, t_env **env); +char *get_cmd_path(char *cmd, t_env *env); +int execute_cmd(t_cmd *cmd, t_env *env); #endif diff --git a/src/env.c b/src/env.c new file mode 100644 index 0000000..3110965 --- /dev/null +++ b/src/env.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 14:31:07 by chuhlig #+# #+# */ +/* Updated: 2024/10/25 19:17:54 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env.h" +#include "get_next_line.h" +#include "libft.h" +#include <stdlib.h> + +void getenvlst(t_env **env, char **en) +{ + char *tmp; + int i; + t_env *current; + + i = 0; + while (en[i] != NULL) + { + tmp = ft_strchr(en[i], '='); + *tmp = '\0'; + current = *env; + current = malloc(sizeof(t_env)); + current->name = ft_strdup(en[i]); + current->value = ft_strdup(tmp + 1); + current->next = *env; + *env = current; + i++; + } +} + +void free_envlst(t_env **env) +{ + t_env *cur; + t_env *new; + + cur = *env; + while (cur) + { + new = cur->next; + free(cur->name); + free(cur->value); + free(cur); + cur = new; + } +} + +char *env_get(t_env *env, char *name) +{ + while (env != NULL) + { + if (!ft_strncmp(env->name, name, ft_strlen(name))) + return (env->value); + env = env->next; + } + return (NULL); +} diff --git a/src/env_to_strlst.c b/src/env_to_strlst.c new file mode 100644 index 0000000..3a58df9 --- /dev/null +++ b/src/env_to_strlst.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_to_strlst.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 14:52:08 by dkaiser #+# #+# */ +/* Updated: 2024/10/21 15:07:33 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "minishell.h" + +static char *get_var_assign(t_env *cur); + +char **env_to_strlst(t_env *env) +{ + int size; + t_env *cur; + char **result; + int i; + + size = 0; + cur = env; + while (cur != NULL) + { + size++; + cur = cur->next; + } + result = malloc(sizeof(char *) * (size + 1)); + if (result == NULL) + return (NULL); + i = 0; + cur = env; + while (i < size) + { + result[i] = get_var_assign(cur); + cur = cur->next; + i++; + } + result[i] = NULL; + return (result); +} + +static char *get_var_assign(t_env *cur) +{ + char *left_side; + char *result; + + left_side = ft_strjoin(cur->name, "="); + if (left_side == NULL) + return (NULL); + result = ft_strjoin(left_side, cur->value); + free(left_side); + return (result); +} diff --git a/src/execute_cmd.c b/src/execute_cmd.c new file mode 100644 index 0000000..6386fc0 --- /dev/null +++ b/src/execute_cmd.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execute_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 13:58:56 by dkaiser #+# #+# */ +/* Updated: 2024/10/25 20:59:22 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include <stdlib.h> +#include <sys/_types/_pid_t.h> +#include <sys/_types/_s_ifmt.h> +#include <sys/fcntl.h> +#include <unistd.h> +#include <fcntl.h> + +int execute_cmd(t_cmd *cmd, t_env *env) +{ + int result; + char *cmd_path; + int fd; + + cmd_path = get_cmd_path(cmd->args[0], env); + cmd->args[0] = cmd_path; + + if (cmd->redirs[0].type == INPUT_FILE) + { + fd = open(cmd->redirs[0].specifier, O_RDONLY); + if (fd < 0) + return (EXIT_FAILURE); + dup2(fd, STDIN_FILENO); + } + else if (cmd->redirs[0].type == INPUT_LIMITER) + { + dbg("INPUT_LIMITER"); + } + if (cmd->redirs[1].type == OUTPUT_APPEND) + { + dbg("OUTPUT_APPEND"); + fd = open(cmd->redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND); + if (fd < 0) + return (EXIT_FAILURE); + dup2(fd, STDOUT_FILENO); + } + else if (cmd->redirs[1].type == OUTPUT_OVERRIDE) + { + fd = open(cmd->redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) + return (EXIT_FAILURE); + dup2(fd, STDOUT_FILENO); + dbg("OUTPUT_OVERRIDE"); + } + result = execve(cmd->args[0], cmd->args, env_to_strlst(env)); + return (result); +} + +static int eval_cmd(t_cmd *cmd, t_env **env) +{ + if (ft_strncmp(cmd->args[0], "pwd", 4) == 0) + pwd(*env); + else if (ft_strncmp(cmd->args[0], "echo", 5) == 0) + echo(cmd->args); + else if (ft_strncmp(cmd->args[0], "env", 4) == 0) + ft_env(*env); + else if (ft_strncmp(cmd->args[0], "cd", 3) == 0) + cd(env, cmd->args); + else if (ft_strncmp(cmd->args[0], "unset", 6) == 0) + unset(cmd->args, env); + else if (ft_strncmp(cmd->args[0], "export", 7) == 0) + export(cmd->args, env); + return (0); +}
\ No newline at end of file diff --git a/src/get_cmd_path.c b/src/get_cmd_path.c new file mode 100644 index 0000000..1ecf393 --- /dev/null +++ b/src/get_cmd_path.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_cmd_path.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:45:47 by dkaiser #+# #+# */ +/* Updated: 2024/10/17 17:11:27 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "minishell.h" + +static char *get_absolute_cmd_path(char *cmd, t_env *env); +static char *find_in_path(char *cmd, t_env *env); +char **get_split_path(t_env *env); + +char *get_cmd_path(char *cmd, t_env *env) +{ + if (cmd[0] == '/') + return (ft_strdup(cmd)); + else if (ft_strchr(cmd, '/')) + return (get_absolute_cmd_path(cmd, env)); + else + return (find_in_path(cmd, env)); +} + +static char *get_absolute_cmd_path(char *cmd, t_env *env) +{ + char *cur_dir; + char *result; + + cur_dir = ft_strjoin(env_get(env, "PWD"), "/"); + if (!cur_dir) + return (NULL); + result = ft_strjoin(cur_dir, cmd); + free(cur_dir); + if (!result) + return (NULL); + if (access(result, X_OK) == -1) + { + free(result); + return (NULL); + } + return (result); +} + +static char *find_in_path(char *cmd, t_env *env) +{ + char *cur_path; + char *cmd_path; + char **path; + + path = get_split_path(env); + cmd_path = NULL; + while (*path) + { + if (cmd_path) + free(cmd_path); + cur_path = ft_strjoin(*path, "/"); + if (!cur_path) + return (NULL); + cmd_path = ft_strjoin(cur_path, cmd); + free(cur_path); + if (!cmd_path) + return (NULL); + if (access(cmd_path, X_OK) != -1) + return (cmd_path); + path++; + } + return (NULL); +} + +char **get_split_path(t_env *env) +{ + char *path; + + path = env_get(env, "PATH"); + return (ft_split(path, ':')); +} diff --git a/src/interpreter.c b/src/interpreter.c index 2a09e6d..c6a4a00 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -3,37 +3,88 @@ /* ::: :::::::: */ /* interpreter.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/05 13:15:24 by dkaiser #+# #+# */ -/* Updated: 2024/08/05 13:33:16 by dkaiser ### ########.fr */ +/* Updated: 2024/10/25 20:59:16 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ +#include "debug_tools.h" #include "minishell.h" +#include <stdlib.h> +#include <sys/_types/_pid_t.h> +#include <sys/cdefs.h> +#include <sys/wait.h> +#include <unistd.h> -static int eval_pipe(t_pipe *pipe); -static int eval_cmd(t_cmd *cmd); +static int eval_rec(t_node *node, t_env *env, int in_fd); -int eval(t_node *node) +int eval(t_node *node, t_env *env) { - if (node->type == PIPE_NODE) - return (eval_pipe(&node->content.pipe)); - else if (node->type == CMD_NODE) - return (eval_cmd(&node->content.cmd)); + pid_t pid; + int result; + + if (node == NULL) + return (EXIT_FAILURE); + result = 0; + pid = fork(); + if (pid < 0) + { + return (EXIT_FAILURE); + } + if (pid == 0) + { + result = eval_rec(node, env, STDIN_FILENO); + exit(result); + } else { - panic(UNREACHABLE); - return (-1); + waitpid(pid, &result, 0); } + return (result); } -static int eval_pipe(t_pipe *pipe) +static int eval_rec(t_node *node, t_env *env, int in_fd) { - return (0); -} + pid_t pid; + int result; + int p[2]; -static int eval_cmd(t_cmd *cmd) -{ - return (0); + result = pipe(p); + if (result == -1) + return (EXIT_FAILURE); + if (node->type == PIPE_NODE) + { + pid = fork(); + if (pid < 0) + { + return (EXIT_FAILURE); + } + if (pid == 0) + { + close(p[0]); + dup2(in_fd, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + result = execute_cmd(&node->content.pipe.left->content.cmd, env); + exit(result); + } + else + { + close(p[1]); + dup2(p[0], STDIN_FILENO); + result = eval_rec(node->content.pipe.right, env, p[0]); + } + } + else if (node->type == CMD_NODE) + { + result = execute_cmd(&node->content.cmd, env); + } + else + { + panic(UNREACHABLE); + return (EXIT_FAILURE); + } + return (result); } + @@ -7,14 +7,21 @@ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:03 by dkaiser #+# #+# */ /* Updated: 2024/08/26 19:55:57 by chuhlig ### ########.fr */ +/* Updated: 2024/10/25 16:06:32 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/minishell.h" -int main(void) +int main(int argc, char *argv[], char *envp[]) { + t_env *env; + + env = NULL; + if (!argc && !argv) + return (1); if (init()) return (1); - repl("Minishell $ "); + getenvlst(&env, envp); + repl("Minishell $ ", &env); } @@ -6,14 +6,14 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 16:07:04 by dkaiser #+# #+# */ -/* Updated: 2024/09/13 16:26:35 by dkaiser ### ########.fr */ +/* Updated: 2024/10/22 17:05:14 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/minishell.h" #include "token.h" -void repl(const char *prompt) +void repl(const char *prompt, t_env **env) { char *input; t_token *token_list; @@ -31,7 +31,10 @@ void repl(const char *prompt) tokenizer(input, &token_list, '\0'); lines = parse(token_list); if (lines) + { print_ast(lines->content); + eval(lines->content, env); + } free(input); } } |
