diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/builtins_part_one.c | 153 | ||||
| -rw-r--r-- | src/builtins_part_three.c | 85 | ||||
| -rw-r--r-- | src/builtins_part_two.c | 39 | ||||
| -rw-r--r-- | src/collect_redirs.c | 147 | ||||
| -rw-r--r-- | src/create_files.c | 65 | ||||
| -rw-r--r-- | src/debug_tools.c | 6 | ||||
| -rw-r--r-- | src/env.c | 25 | ||||
| -rw-r--r-- | src/env_to_strlst.c | 28 | ||||
| -rw-r--r-- | src/env_tools.c | 21 | ||||
| -rw-r--r-- | src/error.c | 30 | ||||
| -rw-r--r-- | src/execute_cmd.c | 110 | ||||
| -rw-r--r-- | src/format_string.c | 118 | ||||
| -rw-r--r-- | src/free_node.c | 79 | ||||
| -rw-r--r-- | src/free_token.c | 36 | ||||
| -rw-r--r-- | src/get_cmd_path.c | 148 | ||||
| -rw-r--r-- | src/handle_redir.c | 103 | ||||
| -rw-r--r-- | src/init.c | 4 | ||||
| -rw-r--r-- | src/interpreter.c | 137 | ||||
| -rw-r--r-- | src/main.c | 11 | ||||
| -rw-r--r-- | src/new_node.c | 9 | ||||
| -rw-r--r-- | src/new_token.c | 7 | ||||
| -rw-r--r-- | src/parse_cmd.c | 16 | ||||
| -rw-r--r-- | src/parser.c | 8 | ||||
| -rw-r--r-- | src/praise_the_norme.c | 30 | ||||
| -rw-r--r-- | src/read_heredoc.c | 76 | ||||
| -rw-r--r-- | src/repl.c | 46 | ||||
| -rw-r--r-- | src/signal_handling.c | 4 | ||||
| -rw-r--r-- | src/tokenizer.c | 25 |
28 files changed, 1046 insertions, 520 deletions
diff --git a/src/builtins_part_one.c b/src/builtins_part_one.c index d64bb54..11989cc 100644 --- a/src/builtins_part_one.c +++ b/src/builtins_part_one.c @@ -6,79 +6,12 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/09 17:01:16 by chuhlig #+# #+# */ -/* Updated: 2025/01/10 14:36:55 by chuhlig ### ########.fr */ +/* Updated: 2025/01/20 19:07:18 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "env.h" - -int echo(char **av) -{ - int i; - int f; - - i = 1; - f = 1; - if (av[1] == NULL || av[1][0] == '\0') - { - write(1, "\n", 1); - return (1); - } - if (ft_strncmp(av[1], "-n", 3) == 0) - { - i++; - f = 0; - } - while (av[i]) - { - write(1, av[i], ft_strlen(av[i])); - i++; - if (av[i]) - write(1, " ", 1); - } - if (f) - write(1, "\n", 1); - return (0); -} - -int pwd(t_env *env) -{ - while (env) - { - if (ft_strncmp(env->name, "PWD", 4) == 0) - { - ft_printf("%s\n", env->value); - break ; - } - env = env->next; - } - return (0); -} - -int ft_env(t_env *env) -{ - while (env != NULL) - { - printf("%s", env->name); - printf("=%s\n", env->value); - env = env->next; - } - return (0); -} - -// int exit(char *av) -// { -// freenode free toke free sequence stop repl free env; -// clear history; -// } -//// - -void free_env_node(t_env *node) -{ - free(node->name); - free(node->value); - free(node); -} +#include <stdio.h> int unset(char **av, t_env **env) { @@ -109,21 +42,12 @@ int unset(char **av, t_env **env) return (0); } -t_env *env_new(char *name) -{ - t_env *result; - - result = malloc(sizeof(t_env)); - if (!result) - return (NULL); - result->name = name; - return (result); -} - t_env *check_existing(t_env *env, char *av) { while (env) { + if (ft_strcmp("$", av) == 0) + return (NULL); if (ft_strcmp(env->name, av) == 0) return (env); env = env->next; @@ -131,31 +55,66 @@ t_env *check_existing(t_env *env, char *av) return (NULL); } -int export(char **av, t_env **env) +void export_export(char *av, t_env **env) { char *tmp; t_env *current; - int i; current = NULL; + tmp = ft_strchr(av, '='); + *tmp = '\0'; + current = check_existing(*env, av); + if (current) + free(current->value); + else + { + current = env_new(ft_strdup(av)); + current->next = *env; + *env = current; + } + current->value = ft_strdup(tmp + 1); +} + +int is_valid_identifier(char *str) +{ + int i; + + i = 0; + if (!ft_isalpha(str[0]) && str[0] != '_') + return (0); + while (str[i] && str[i] != '=') + { + if (!ft_isalnum(str[i]) && str[i] != '_') + return (0); + i++; + } + return (1); +} + +int export(char **av, t_env **env, int f) +{ + char *equal_sign; + int i; + i = 0; while (av[++i]) { - if ((ft_strchr(av[i], '='))) + equal_sign = ft_strchr(av[i], '='); + if (equal_sign) + *equal_sign = '\0'; + if (!is_valid_identifier(av[i])) { - tmp = ft_strchr(av[i], '='); - *tmp = '\0'; - current = check_existing(*env, av[i]); - if (current) - free(current->value); - else - { - current = env_new(ft_strdup(av[i])); - current->next = *env; - *env = current; - } - current->value = ft_strdup(tmp + 1); + write(1, "Minishell $ export: not a valid identifier\n", 43); + if (equal_sign) + *equal_sign = '='; + f++; + continue ; + } + if (equal_sign) + { + *equal_sign = '='; + export_export(av[i], env); } } - return (0); -}
\ No newline at end of file + return (check_flag(f)); +} diff --git a/src/builtins_part_three.c b/src/builtins_part_three.c new file mode 100644 index 0000000..3b9b100 --- /dev/null +++ b/src/builtins_part_three.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtins_part_three.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/18 18:29:24 by chuhlig #+# #+# */ +/* Updated: 2025/01/21 16:15:19 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env.h" + +void exit_shell(t_env **env, int exit_status) +{ + free_envlst(env); + exit(exit_status); +} + +int builtin_exit(char **av, t_env **env) +{ + int exit_status; + + if (av[1] && !av[2]) + exit_status = ft_atoi(av[1]); + else if (av[2]) + exit_status = 1; + else + exit_status = 0; + exit_shell(env, exit_status); + return (exit_status); +} + +void set_return_code(int return_code, t_env **env) +{ + t_env *cur; + + cur = check_existing(*env, "?"); + if (cur) + free(cur->value); + else + { + cur = env_new(ft_strdup("?")); + cur->next = *env; + *env = cur; + } + cur->value = ft_itoa(return_code); +} + +int echo(char **av) +{ + int i; + int f; + + i = 1; + f = 1; + if (av[1] == NULL || av[1][0] == '\0') + { + write(1, "\n", 1); + return (0); + } + if (ft_strncmp(av[1], "-n", 3) == 0) + { + i++; + f = 0; + } + while (av[i]) + { + write(1, av[i], ft_strlen(av[i])); + i++; + if (av[i]) + write(1, " ", 1); + } + if (f) + write(1, "\n", 1); + return (0); +} + +int check_flag(int f) +{ + if (f) + return (1); + return (0); +} diff --git a/src/builtins_part_two.c b/src/builtins_part_two.c index f54e04f..2382f25 100644 --- a/src/builtins_part_two.c +++ b/src/builtins_part_two.c @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/25 20:52:16 by chuhlig #+# #+# */ -/* Updated: 2024/12/20 18:53:03 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 18:44:03 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,17 +15,14 @@ void update_oldpwd(t_env **env) { t_env *current; - t_env *prev; char cwd[1028]; char *tmp; - prev = NULL; current = *env; while (current) { if (ft_strncmp(current->name, "OLDPWD", 6) == 0) break ; - prev = current; current = current->next; } getcwd(cwd, sizeof(cwd)); @@ -37,17 +34,14 @@ void update_oldpwd(t_env **env) void update_pwd(t_env **env) { t_env *current; - t_env *prev; char cwd[1028]; char *tmp; - prev = NULL; current = *env; while (current) { if (ft_strncmp(current->name, "PWD", 3) == 0) break ; - prev = current; current = current->next; } getcwd(cwd, sizeof(cwd)); @@ -72,6 +66,7 @@ int cd(t_env **env, char **av) } if (chdir(current->value) == -1) return (1); + update_pwd(env); } else { @@ -82,3 +77,33 @@ int cd(t_env **env, char **av) } return (0); } + +int pwd(t_env *env) +{ + while (env) + { + if (ft_strncmp(env->name, "PWD", 4) == 0) + { + ft_printf("%s\n", env->value); + break ; + } + env = env->next; + } + return (0); +} + +int ft_env(t_env *env) +{ + while (env != NULL) + { + if (ft_strchr(env->name, '?')) + { + env = env->next; + continue ; + } + printf("%s", env->name); + printf("=%s\n", env->value); + env = env->next; + } + return (0); +} diff --git a/src/collect_redirs.c b/src/collect_redirs.c index be0e00f..67ab8f8 100644 --- a/src/collect_redirs.c +++ b/src/collect_redirs.c @@ -6,121 +6,110 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/02 13:49:31 by dkaiser #+# #+# */ -/* Updated: 2025/01/13 09:52:00 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 20:19:48 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +#include <stdlib.h> -static void collect_and_check_redir(t_redirection *result, t_token **cur); -static void set_redir(t_redirection *redir, int type, char *specifier); +static void collect_and_check_redir(t_redirection *result, + t_token **cur, t_minidata *data, t_token **tokens); +static t_redirection *set_redir(t_redirection *redir, int type, char *spec, + t_env *env); +static int set_heredoc_data(t_token *cur, t_redirection *result, + t_env *env); -static char *read_heredoc(char *delimiter) -{ - char *line; - char *result; - char *temp; - size_t total_length; - size_t line_length; - - total_length = 0; - result = NULL; - while (1) - { - line = readline("> "); - if (!line || ft_strcmp(line, delimiter) == 0) - { - free(line); - break ; - } - line_length = ft_strlen(line) + 1; - temp = malloc(total_length + line_length + 1); - if (!temp) - { - perror("malloc"); - free(result); - return (NULL); - } - if (result) - { - ft_strcpy(temp, result); - free(result); - } - else - { - temp[0] = '\0'; - } - ft_strcat(temp, line); - ft_strcat(temp, "\n"); - result = temp; - total_length += line_length; - free(line); - } - return (result); -} - -t_redirection *collect_redirs(t_token **tokens) +t_redirection *collect_redirs(t_token **tokens, t_env *env, + t_list **create_files) { t_redirection *result; t_token *cur; + t_minidata data; cur = *tokens; result = malloc(sizeof(t_redirection) * 2); if (result == NULL) return (free_tokens(*tokens), NULL); - set_redir(&result[0], 0, NULL); - set_redir(&result[1], 0, NULL); - while (cur != NULL && cur->next != NULL) + free(set_redir(&result[0], 0, NULL, env)); + free(set_redir(&result[1], 0, NULL, env)); + data.create_files = create_files; + data.env = env; + while (cur != NULL) { if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN) - collect_and_check_redir(result, &cur); + collect_and_check_redir(result, &cur, &data, tokens); else if (cur->type == REDIR_TOKEN) return (free(result), NULL); else cur = cur->next; } - if (cur && cur->type == REDIR_TOKEN) - return (free(result), NULL); return (result); } -static void set_redir(t_redirection *redir, int type, char *specifier) +static void collect_and_check_redir(t_redirection *result, t_token **cur, + t_minidata *data, t_token **tokens) { + char *str; + + if ((*cur)->content.redir_type != INPUT_LIMITER) + str = ft_strdup((*cur)->next->content.string); + if ((*cur)->content.redir_type == INPUT_LIMITER) + { + if (!set_heredoc_data(*cur, result, data->env)) + return ; + } + else if ((*cur)->content.redir_type == INPUT_FILE) + q4fc(data->create_files, set_redir(&result[0], INPUT_FILE, + format_string(str, data->env, 0), data->env)); + else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE) + q4fc(data->create_files, set_redir(&result[1], OUTPUT_OVERRIDE, + format_string(str, data->env, 0), data->env)); + else if ((*cur)->content.redir_type == OUTPUT_APPEND) + q4fc(data->create_files, set_redir(&result[1], OUTPUT_APPEND, + format_string(str, data->env, 0), data->env)); + i_love_the_norme(cur, tokens); +} + +static t_redirection *set_redir(t_redirection *redir, int type, char *spec, + t_env *env) +{ + t_redirection *result; + redir->type = type; - redir->specifier = specifier; + // if (redir->specifier != NULL) + // free(redir->specifier); + if (spec != NULL) + redir->specifier = format_string(spec, env, ft_atoi("0")); + else + redir->specifier = spec; + if (redir->type != INPUT_LIMITER) + { + result = malloc(sizeof(t_redirection)); + if (!result) + return (NULL); + result->type = type; + result->specifier = spec; + return (result); + } + return (NULL); } -static void collect_and_check_redir(t_redirection *result, t_token **cur) +static int set_heredoc_data(t_token *cur, t_redirection *result, t_env *env) { char *heredoc_data; - t_token *next_token; heredoc_data = NULL; - if ((*cur)->content.redir_type == INPUT_LIMITER) + if (cur->content.redir_type == INPUT_LIMITER) { - heredoc_data = read_heredoc((*cur)->next->content.string); + heredoc_data = read_heredoc(cur->next->content.string); if (!heredoc_data) { perror("Heredoc allocation failed"); - return ; + return (0); } - set_redir(&result[0], INPUT_LIMITER, heredoc_data); - } - else if ((*cur)->content.redir_type == INPUT_FILE) - set_redir(&result[0], INPUT_FILE, ft_strdup((*cur)->next->content.string)); - else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE) - set_redir(&result[1], OUTPUT_OVERRIDE, ft_strdup((*cur)->next->content.string)); - else if ((*cur)->content.redir_type == OUTPUT_APPEND) - set_redir(&result[1], OUTPUT_APPEND, ft_strdup((*cur)->next->content.string)); - else - printf("Unknown redirection type encountered\n"); - next_token = (*cur)->next; - free_token_and_connect(*cur); - if (next_token) - { - *cur = next_token->next; - free_token_and_connect(next_token); + set_redir(&result[0], INPUT_LIMITER, heredoc_data, env); } - else - *cur = NULL; + set_redir(&result[0], INPUT_LIMITER, heredoc_data, env); + return (1); } diff --git a/src/create_files.c b/src/create_files.c new file mode 100644 index 0000000..8c04d8f --- /dev/null +++ b/src/create_files.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* create_files.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/16 16:23:51 by dkaiser #+# #+# */ +/* Updated: 2025/01/21 13:17:47 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include <sys/fcntl.h> +#include <unistd.h> + +static int cant_write(char *filename); +static void create_file(char *filename, int mode); + +int create_files(t_list *files) +{ + t_redirection *file; + + while (files) + { + if (files->content != NULL) + { + file = (t_redirection *)files->content; + if (file->type == INPUT_FILE && (access(file->specifier, F_OK) == -1 + || access(file->specifier, R_OK) == -1)) + return (EXIT_FAILURE); + if (cant_write(file->specifier)) + break ; + if (file->type == OUTPUT_OVERRIDE) + create_file(file->specifier, O_TRUNC); + else if (file->type == OUTPUT_APPEND) + create_file(file->specifier, O_APPEND); + if (files->next == NULL) + break ; + if (((t_redirection *)files->next->content)->type == 0) + break ; + } + files = files->next; + } + return (EXIT_SUCCESS); +} + +static int cant_write(char *filename) +{ + return (access(filename, F_OK) != -1 && access(filename, W_OK) == -1); +} + +static void create_file(char *filename, int mode) +{ + int fd; + + fd = open(filename, O_WRONLY | O_CREAT | mode, 0644); + if (fd != -1) + close(fd); +} + +void q4fc(t_list **queue, t_redirection *redir) +{ + ft_lstadd_back(queue, ft_lstnew(redir)); +} diff --git a/src/debug_tools.c b/src/debug_tools.c index de59703..6bee1b0 100644 --- a/src/debug_tools.c +++ b/src/debug_tools.c @@ -3,14 +3,16 @@ /* ::: :::::::: */ /* debug_tools.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 15:34:14 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 15:04:43 by dkaiser ### ########.fr */ +/* Updated: 2025/01/20 12:50:36 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "debug_tools.h" +#include <stdio.h> +#include <stdarg.h> void dbg(char *msg) { @@ -6,11 +6,12 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/17 14:31:07 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:36:14 by chuhlig ### ########.fr */ +/* Updated: 2025/01/20 19:12:43 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "env.h" +#include "minishell.h" #include <stdlib.h> void getenvlst(t_env **env, char **en) @@ -54,9 +55,27 @@ char *env_get(t_env *env, char *name) { while (env != NULL) { - if (!ft_strncmp(env->name, name, ft_strlen(name))) + if (!ft_strncmp(env->name, name, ft_strlen(env->name))) return (env->value); env = env->next; } return (NULL); -}
\ No newline at end of file +} + +t_env *env_new(char *name) +{ + t_env *result; + + result = malloc(sizeof(t_env)); + if (!result) + return (NULL); + result->name = name; + return (result); +} + +void free_env_node(t_env *node) +{ + free(node->name); + free(node->value); + free(node); +} diff --git a/src/env_to_strlst.c b/src/env_to_strlst.c index c4c98c3..5806d96 100644 --- a/src/env_to_strlst.c +++ b/src/env_to_strlst.c @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:22:28 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:22:36 by chuhlig ### ########.fr */ +/* Updated: 2025/01/18 18:50:49 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,20 +15,32 @@ static char *get_var_assign(t_env *cur); -char **env_to_strlst(t_env *env) +static int getsize(t_env *env) { int size; t_env *cur; - char **result; - int i; size = 0; cur = env; - while (cur != NULL) + while (cur) { - size++; + if (!ft_strchr(cur->name, '?')) + size++; cur = cur->next; } + return (size); +} + +char **env_to_strlst(t_env *env) +{ + int size; + t_env *cur; + char **result; + int i; + + size = 0; + cur = env; + size = getsize(env); result = malloc(sizeof(char *) * (size + 1)); if (result == NULL) return (NULL); @@ -36,6 +48,8 @@ char **env_to_strlst(t_env *env) cur = env; while (i < size) { + if (ft_strchr(cur->name, '?')) + cur = cur->next; result[i] = get_var_assign(cur); cur = cur->next; i++; @@ -55,4 +69,4 @@ static char *get_var_assign(t_env *cur) result = ft_strjoin(left_side, cur->value); free(left_side); return (result); -}
\ No newline at end of file +} diff --git a/src/env_tools.c b/src/env_tools.c new file mode 100644 index 0000000..f1c3748 --- /dev/null +++ b/src/env_tools.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_tools.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/15 16:14:31 by dkaiser #+# #+# */ +/* Updated: 2025/01/22 00:01:03 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +// char **get_split_path(t_env *env) +// { +// char *path; + +// path = env_get(env, "PATH"); +// return (ft_split(path, ':')); +// } diff --git a/src/error.c b/src/error.c new file mode 100644 index 0000000..2ca60b2 --- /dev/null +++ b/src/error.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/15 16:35:53 by dkaiser #+# #+# */ +/* Updated: 2025/01/20 18:12:40 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include <errno.h> + +void *error(int err_code, char *err_text, int exit_code, int *ret_code) +{ + errno = err_code; + perror(err_text); + if (ret_code != NULL) + *ret_code = exit_code; + return (NULL); +} + +void command_not_found_error(char *cmd) +{ + ft_printf("%s:", cmd); + ft_putstr_fd(" command not found", 2); + ft_printf("\n"); +} diff --git a/src/execute_cmd.c b/src/execute_cmd.c index 803d88f..012391f 100644 --- a/src/execute_cmd.c +++ b/src/execute_cmd.c @@ -6,72 +6,100 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:21:35 by chuhlig #+# #+# */ -/* Updated: 2025/01/13 09:50:56 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 23:52:38 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -#include <fcntl.h> +#include <stdio.h> #include <stdlib.h> -#include <sys/_types/_pid_t.h> -#include <sys/_types/_s_ifmt.h> -#include <sys/fcntl.h> -#include <unistd.h> + +static void establish_pipeline(int original_stdin, int original_stdout); +static int exec_cmd(t_cmd *cmd, t_env **env, int original_std[2], int result); + +int is_builtin(char *cmd) +{ + return ((ft_strcmp(cmd, "export") == 0) || (ft_strcmp(cmd, "unset") == 0) + || (ft_strcmp(cmd, "cd") == 0) || (ft_strcmp(cmd, "exit") == 0) + || (ft_strcmp(cmd, "echo") == 0) || (ft_strcmp(cmd, "pwd") == 0) + || (ft_strcmp(cmd, "env") == 0)); +} + +int execute_builtin(char **args, t_env **env) +{ + if (ft_strcmp(args[0], "export") == 0) + return (export(args, env, ft_atoi("0"))); + else if (ft_strcmp(args[0], "unset") == 0) + return (unset(args, env)); + else if (ft_strcmp(args[0], "cd") == 0) + return (cd(env, args)); + else if (ft_strcmp(args[0], "echo") == 0) + return (echo(args)); + else if (ft_strcmp(args[0], "pwd") == 0) + return (pwd(*env)); + else if (ft_strcmp(args[0], "env") == 0) + return (ft_env(*env)); + else if (ft_strcmp(args[0], "exit") == 0) + return (builtin_exit(args, env)); + return (1); +} int execute_cmd(t_cmd *cmd, t_env **env) { - char *cmd_path; - pid_t pid; - int status; - int result; - int original_stdout; - int original_stdin; + int original_std[2]; + int result; - original_stdout = dup(STDOUT_FILENO); - original_stdin = dup(STDIN_FILENO); + original_std[1] = dup(STDOUT_FILENO); + original_std[0] = dup(STDIN_FILENO); + create_files(cmd->create_files); if (handle_redirections(cmd->redirs) == -1) { - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); + establish_pipeline(original_std[0], original_std[1]); return (EXIT_FAILURE); } if (is_builtin(cmd->args[0])) { result = execute_builtin(cmd->args, env); - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); + establish_pipeline(original_std[0], original_std[1]); return (result); } + return (exec_cmd(cmd, env, original_std, EXIT_SUCCESS)); +} + +static void establish_pipeline(int original_stdin, int original_stdout) +{ + dup2(original_stdout, STDOUT_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdout); + close(original_stdin); +} + +static int exec_cmd(t_cmd *cmd, t_env **env, int original_std[2], int result) +{ + int i; + int status; + char *cmd_path; + pid_t pid; + pid = fork(); if (pid == -1) { perror("fork"); - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); + establish_pipeline(original_std[0], original_std[1]); return (EXIT_FAILURE); } if (pid == 0) { - cmd_path = get_cmd_path(cmd->args[0], *env); - if (!cmd_path) - { - printf("%s: command not found\n", cmd->args[0]); - exit(EXIT_FAILURE); - } - execve(cmd_path, cmd->args, env_to_strlst(*env)); - perror("execve"); - exit(EXIT_FAILURE); + i = 0; + while (cmd->args[i][0] == '\0') + i++; + cmd_path = get_cmd_path(cmd->args[i], *env, &result); + if (cmd_path != NULL) + execve(cmd_path, &(cmd->args[i]), env_to_strlst(*env)); + free(cmd_path); + exit(result); } waitpid(pid, &status, 0); - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); - return (WEXITSTATUS(status)); -}
\ No newline at end of file + establish_pipeline(original_std[0], original_std[1]); + return ((status >> 8) & 255); +} diff --git a/src/format_string.c b/src/format_string.c index bd7f703..775a3da 100644 --- a/src/format_string.c +++ b/src/format_string.c @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:30:11 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:31:54 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 23:25:20 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,52 +14,18 @@ #include "libft.h" #include "minishell.h" -static void append_slice(char **dst, char *src, int start, int end); -static void append_var(char **dst, char *src, int *pos, t_env *env); - -enum e_format_mode -{ - LITERAL = 1, - VARIABLE = 2, -}; - -char *format_string(char *str, t_env *env) +void append_var_exit_code(char **dst, t_env *env) { + char *exit_code; char *result; - int pos; - int start; - int mode; - pos = 0; - start = 0; - mode = 0; - result = NULL; - if (str == NULL) - return (NULL); - while (str[pos] != '\0') + exit_code = env_get(env, "?"); + if (exit_code) { - if (str[pos] == '\'') - { - append_slice(&result, str, start, pos); - start = pos + 1; - mode ^= LITERAL; - } - if (str[pos] == '"' && !(mode & LITERAL)) - { - append_slice(&result, str, start, pos); - start = pos + 1; - } - if (str[pos] == '$' && !(mode & LITERAL)) - { - append_slice(&result, str, start, pos); - append_var(&result, str, &pos, env); - start = pos; - continue ; - } - pos++; + result = ft_strjoin(*dst, exit_code); + free(*dst); + *dst = result; } - append_slice(&result, str, start, pos); - return (result); } static void append_slice(char **dst, char *src, int start, int end) @@ -71,9 +37,7 @@ static void append_slice(char **dst, char *src, int start, int end) if (*dst != NULL) len = ft_strlen(*dst); else - { len = 0; - } result = malloc(len + (end - start) + 1); if (!result) return ; @@ -99,27 +63,63 @@ static void append_var(char **dst, char *src, int *pos, t_env *env) i = 0; *pos += 1; - while (src[*pos + i] != '\0' && src[*pos + i] != '\'' && src[*pos - + i] != '"' && src[*pos + i] != '$') - { + while (ft_isalnum(src[*pos + i]) || src[*pos + i] == '_') i++; - } - var = malloc(i + 1); - if (var == NULL) + if (i == 0) return ; - var[i] = '\0'; - i--; - while (i >= 0) - { - var[i] = src[*pos + i]; - i--; - } + var = ft_substr(src, *pos, i); value = env_get(env, var); - if (value != NULL) + if (value) { result = ft_strjoin(*dst, value); free(*dst); *dst = result; } - *pos += ft_strlen(var); + *pos += i; + free(var); +} + +static void handle_dollar_sign(char **result, char *str, int *pos, t_env *env) +{ + if (str[*pos + 1] == '?') + { + append_var_exit_code(result, env); + *pos += 2; + } + else if (ft_isalnum(str[*pos + 1]) || str[*pos + 1] == '_') + append_var(result, str, pos, env); + else + { + append_slice(result, str, *pos, *pos + 1); + (*pos)++; + } +} + +char *format_string(char *str, t_env *env, int is_literal) +{ + char *result; + int pos; + int start; + + pos = 0; + start = 0; + result = NULL; + if (!str) + return (NULL); + while (str[pos]) + { + if (str[pos] == '\'' || (str[pos] == '\"' && !is_literal) + || (str[pos] == '$' && !is_literal)) + { + append_slice(&result, str, start, pos); + if (str[pos] == '$') + handle_dollar_sign(&result, str, &pos, env); + else + is_literal ^= (str[pos++] == '\''); + start = pos; + continue ; + } + pos++; + } + return (append_slice(&result, str, start, pos), result); } diff --git a/src/free_node.c b/src/free_node.c index 6eae059..d866727 100644 --- a/src/free_node.c +++ b/src/free_node.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* free_node.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:41:46 by dkaiser #+# #+# */ -/* Updated: 2024/08/11 12:26:20 by dkaiser ### ########.fr */ +/* Updated: 2025/01/22 01:53:34 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,18 +14,64 @@ static void free_pipe_node(t_node *node); static void free_cmd_node(t_node *node); +static void free_file(void *arg); + +// void free_node(t_node *node) +// { +// if (node->type == PIPE_NODE) +// free_pipe_node(node); +// else if (node->type == CMD_NODE) +// free_cmd_node(node); +// else if (node->type == STRING_NODE) +// free(node->content.string); +// else +// panic(UNREACHABLE); +// free(node); +// } +void free_redirections(t_redirection redirs[2]) +{ + for (int i = 0; i < 2; i++) + { + if (redirs[i].specifier) + free(redirs[i].specifier); + } +} void free_node(t_node *node) { - if (node->type == PIPE_NODE) - free_pipe_node(node); - else if (node->type == CMD_NODE) - free_cmd_node(node); - else if (node->type == STRING_NODE) - free(node->content.string); - else - panic(UNREACHABLE); - free(node); + if (!node) + return; + + if (node->type == PIPE_NODE) + { + free_node(node->content.pipe.left); + free_node(node->content.pipe.right); + } + else if (node->type == CMD_NODE) + { + if (node->content.cmd.args) + { + for (int i = 0; node->content.cmd.args[i]; i++) + free(node->content.cmd.args[i]); + free(node->content.cmd.args); + } + free_redirections(node->content.cmd.redirs); + // Assuming create_files is a list of dynamically allocated strings + t_list *current = node->content.cmd.create_files; + t_list *next; + while (current) + { + next = current->next; + free(current->content); + free(current); + current = next; + } + } + else if (node->type == STRING_NODE) + { + free(node->content.string); + } + free(node); } static void free_pipe_node(t_node *node) @@ -51,4 +97,15 @@ static void free_cmd_node(t_node *node) if (node->content.cmd.redirs[1].type != 0 && node->content.cmd.redirs[0].specifier != NULL) free(node->content.cmd.redirs[1].specifier); + if (node->content.cmd.create_files != NULL) + ft_lstclear(&node->content.cmd.create_files, free_file); +} + +static void free_file(void *arg) +{ + t_redirection *file; + + file = (t_redirection *)arg; + free(file->specifier); + free(file); } diff --git a/src/free_token.c b/src/free_token.c index 9b035ac..64278a8 100644 --- a/src/free_token.c +++ b/src/free_token.c @@ -3,14 +3,15 @@ /* ::: :::::::: */ /* free_token.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 14:38:57 by dkaiser #+# #+# */ -/* Updated: 2024/08/02 14:23:56 by dkaiser ### ########.fr */ +/* Updated: 2025/01/22 00:07:58 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "token.h" +#include "debug_tools.h" void free_token(t_token *token) { @@ -18,7 +19,10 @@ void free_token(t_token *token) token->previous->next = NULL; if (token->next != NULL) token->next->previous = NULL; - free(token); + // if (token->type == STRING_TOKEN && token->content.string != NULL) + // free(token->content.string); // Ensure content is freed + free(token);//maybe free token + token = NULL; } void free_token_and_connect(t_token *token) @@ -28,14 +32,26 @@ void free_token_and_connect(t_token *token) if (token->next != NULL) token->next->previous = token->previous; free(token); + token = NULL; } -void free_tokens(t_token *tokens) +// void free_tokens(t_token *tokens) +// { +// while (tokens->next != NULL) +// { +// tokens = tokens->next; +// free_token(tokens->previous); +// } +// free_token(tokens); +// } +void free_tokens(t_token *tokens) { - while (tokens->next != NULL) - { - tokens = tokens->next; - free_token(tokens->previous); - } - free_token(tokens); + t_token *tmp; + + while (tokens) + { + tmp = tokens; + tokens = tokens->next; + free_token(tmp); // Ensure each token is freed + } } diff --git a/src/get_cmd_path.c b/src/get_cmd_path.c index 8a27584..713c397 100644 --- a/src/get_cmd_path.c +++ b/src/get_cmd_path.c @@ -6,28 +6,35 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:19:59 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:20:08 by chuhlig ### ########.fr */ +/* Updated: 2025/01/22 00:01:48 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" #include "minishell.h" +#include <errno.h> +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/unistd.h> +#include <unistd.h> -static char *get_absolute_cmd_path(char *cmd, t_env *env); -static char *find_in_path(char *cmd, t_env *env); +static char *get_simple_cmd_path(char *cmd, int *return_code); +static char *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code); +static char *find_in_path(char *cmd, t_env *env, int *return_code); char **get_split_path(t_env *env); +static int is_directory(char *path); -char *get_cmd_path(char *cmd, t_env *env) +char *get_cmd_path(char *cmd, t_env *env, int *return_code) { if (cmd[0] == '/') - return (ft_strdup(cmd)); + return (get_simple_cmd_path(cmd, return_code)); else if (ft_strchr(cmd, '/')) - return (get_absolute_cmd_path(cmd, env)); + return (get_absolute_cmd_path(cmd, env, return_code)); else - return (find_in_path(cmd, env)); + return (find_in_path(cmd, env, return_code)); } -static char *get_absolute_cmd_path(char *cmd, t_env *env) +static char *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code) { char *cur_dir; char *result; @@ -38,45 +45,118 @@ static char *get_absolute_cmd_path(char *cmd, t_env *env) result = ft_strjoin(cur_dir, cmd); free(cur_dir); if (!result) - return (NULL); + return (error(ENOENT, cmd, 127, return_code)); + if (access(result, F_OK) == -1) + { + free(result); + return (error(ENOENT, cmd, 127, return_code)); + } if (access(result, X_OK) == -1) { free(result); - return (NULL); + return (error(EACCES, cmd, 126, return_code)); } + if (is_directory(cmd)) + return (error(EISDIR, cmd, 126, return_code)); return (result); } -static char *find_in_path(char *cmd, t_env *env) +void free_split_path(char **path) +{ + char **tmp = path; + while (*tmp) + { + free(*tmp); + tmp++; + } + free(path); +} + +char **get_split_path(t_env *env) { - char *cur_path; - char *cmd_path; - char **path; + char *path_env; + char **split_path; - path = get_split_path(env); - cmd_path = NULL; - while (*path) + path_env = env_get(env, "PATH"); + if (!path_env) + return (NULL); + split_path = ft_split(path_env, ':'); + free(path_env); + return (split_path); +} + +static char *find_in_path(char *cmd, t_env *env, int *return_code) +{ + char *cur_path; + char *cmd_path; + char **path; + char **path_start; // To keep track of the start of the path array + + path = get_split_path(env); + path_start = path; // Save the start of the path array + cmd_path = NULL; + while (*path) + { + if (cmd_path) + free(cmd_path); + cur_path = ft_strjoin(*path, "/"); + if (!cur_path) + { + free_split_path(path_start); // Free the entire path array + return (NULL); + } + cmd_path = ft_strjoin(cur_path, cmd); + free(cur_path); + if (!cmd_path) + { + free_split_path(path_start); // Free the entire path array + return (NULL); + } + if (access(cmd_path, X_OK) != -1) + { + free_split_path(path_start); // Free the entire path array + return (cmd_path); + } + path++; + } + free_split_path(path_start); // Free the entire path array + *return_code = 127; + command_not_found_error(cmd); + return (NULL); +} + +static char *get_simple_cmd_path(char *cmd, int *return_code) +{ + char *result; + + result = ft_strdup(cmd); + if (!result) + return (NULL); + if (access(result, F_OK) == -1) + { + free(result); + return (error(ENOENT, cmd, 127, return_code)); + } + if (access(result, X_OK) == -1) { - 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++; + free(result); + return (error(EACCES, cmd, 126, return_code)); } - return (NULL); + if (is_directory(cmd)) + { + free(result); + return (error(EISDIR, cmd, 126, return_code)); + } + return (result); } -char **get_split_path(t_env *env) +static int is_directory(char *path) { - char *path; + struct stat path_stat; - path = env_get(env, "PATH"); - return (ft_split(path, ':')); + stat(path, &path_stat); + if ((path_stat.st_mode & S_IFMT) == S_IFDIR) + return (1); + else + return (0); } diff --git a/src/handle_redir.c b/src/handle_redir.c new file mode 100644 index 0000000..e8a1010 --- /dev/null +++ b/src/handle_redir.c @@ -0,0 +1,103 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* handle_redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/18 18:34:51 by chuhlig #+# #+# */ +/* Updated: 2025/01/20 14:59:38 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int handle_input_redirection(t_redirection *redir) +{ + int fd; + + if (redir->type == INPUT_FILE) + { + fd = open_file(redir->specifier, O_RDONLY, 0); + if (fd < 0) + return (-1); + dup2(fd, STDIN_FILENO); + close(fd); + } + else if (redir->type == INPUT_LIMITER) + { + fd = open_file("/tmp/heredoc_tmp", O_WRONLY | O_TRUNC, 0644); + if (fd < 0) + return (-1); + write(fd, redir->specifier, ft_strlen(redir->specifier)); + close(fd); + fd = open_file("/tmp/heredoc_tmp", O_RDONLY, 0); + if (fd < 0) + return (-1); + dup2(fd, STDIN_FILENO); + close(fd); + } + return (0); +} + +int handle_output_redirection(t_redirection *redir) +{ + int fd; + + if (redir->type == OUTPUT_OVERRIDE) + { + fd = open_file(redir->specifier, O_WRONLY | O_TRUNC, 0644); + if (fd < 0) + return (-1); + dup2(fd, STDOUT_FILENO); + close(fd); + } + else if (redir->type == OUTPUT_APPEND) + { + fd = open_file(redir->specifier, O_WRONLY | O_APPEND, 0644); + if (fd < 0) + return (-1); + dup2(fd, STDOUT_FILENO); + close(fd); + } + return (0); +} + +int handle_redirections(t_redirection *redirs) +{ + if (redirs[0].type == INPUT_FILE || redirs[0].type == INPUT_LIMITER) + { + if (handle_input_redirection(&redirs[0]) < 0) + return (-1); + } + if (redirs[1].type == OUTPUT_OVERRIDE || redirs[1].type == OUTPUT_APPEND) + { + if (handle_output_redirection(&redirs[1]) < 0) + return (-1); + } + return (0); +} + +int handle_pipe_parent(int p[2], t_node *node, t_env **env) +{ + int original_stdin; + int result; + + close(p[1]); + original_stdin = dup(STDIN_FILENO); + dup2(p[0], STDIN_FILENO); + result = eval_rec(node->content.pipe.right, env, p[0]); + dup2(original_stdin, STDIN_FILENO); + close(original_stdin); + close(p[0]); + return (result); +} + +int handle_pipe_child(int p[2], t_node *node, t_env **env, int in_fd) +{ + close(p[0]); + dup2(in_fd, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + close(p[1]); + exit(eval_rec(node->content.pipe.left, env, in_fd)); +} @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* init.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 15:02:24 by dkaiser #+# #+# */ -/* Updated: 2024/06/24 15:25:57 by dkaiser ### ########.fr */ +/* Updated: 2025/01/13 17:45:46 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/interpreter.c b/src/interpreter.c index 7b0306f..11f0620 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -6,154 +6,53 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:15:49 by chuhlig #+# #+# */ -/* Updated: 2025/01/13 09:53:33 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 16:35:38 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> -#include <sys/fcntl.h> -#include <sys/types.h> -int is_builtin(char *cmd) -{ - return ((ft_strcmp(cmd, "export") == 0) - || (ft_strcmp(cmd, "unset") == 0) - || (ft_strcmp(cmd, "cd") == 0) - || (ft_strcmp(cmd, "exit") == 0) - || (ft_strcmp(cmd, "echo") == 0) - || (ft_strcmp(cmd, "pwd") == 0) - || (ft_strcmp(cmd, "env") == 0)); -} - -int execute_builtin(char **args, t_env **env) -{ - if (ft_strcmp(args[0], "export") == 0) - return (export(args, env)); - else if (ft_strcmp(args[0], "unset") == 0) - return (unset(args, env)); - else if (ft_strcmp(args[0], "cd") == 0) - return (cd(env, args)); - else if (ft_strcmp(args[0], "exit") == 0) - return (EXIT_SUCCESS); - else if (ft_strcmp(args[0], "echo") == 0) - return (echo(args)); - else if (ft_strcmp(args[0], "pwd") == 0) - return (pwd(*env)); - else if (ft_strcmp(args[0], "env") == 0) - return (ft_env(*env)); - return (1); -} +int eval_rec(t_node *node, t_env **env, int in_fd); -static int handle_redirections(t_redirection *redirs) +int open_file(char *path, int flags, int mode) { int fd; - if (redirs[0].type == INPUT_FILE) - { - fd = open(redirs[0].specifier, O_RDONLY); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDIN_FILENO); - close(fd); - } - else if (redirs[0].type == INPUT_LIMITER) - { - fd = open("/tmp/heredoc_tmp", O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - write(fd, redirs[0].specifier, ft_strlen(redirs[0].specifier)); - close(fd); - fd = open("/tmp/heredoc_tmp", O_RDONLY); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDIN_FILENO); - close(fd); - } - if (redirs[1].type == OUTPUT_OVERRIDE) - { - fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDOUT_FILENO); - close(fd); - } - else if (redirs[1].type == OUTPUT_APPEND) - { - fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDOUT_FILENO); - close(fd); - } - return (0); - } + fd = open(path, flags, mode); + if (fd < 0) + perror(path); + return (fd); +} -static int eval_rec(t_node *node, t_env **env, int in_fd) +int eval_rec(t_node *node, t_env **env, int in_fd) { - pid_t pid; int p[2]; + pid_t pid; int result; - int status; - int original_stdin; if (node->type == PIPE_NODE) { - pipe(p); + if (pipe(p) == -1) + return (perror("pipe"), EXIT_FAILURE); pid = fork(); + if (pid == -1) + return (perror("fork"), close(p[0]), close(p[1]), EXIT_FAILURE); if (pid == 0) - { - close(p[0]); - dup2(in_fd, STDIN_FILENO); - dup2(p[1], STDOUT_FILENO); - result = eval_rec(node->content.pipe.left, env, in_fd); - exit(result); - } - else - { - close(p[1]); - original_stdin = dup(STDIN_FILENO); - dup2(p[0], STDIN_FILENO); - result = eval_rec(node->content.pipe.right, env, p[0]); - waitpid(pid, &status, 0); - dup2(original_stdin, STDIN_FILENO); - close(original_stdin); - } + handle_pipe_child(p, node, env, in_fd); + result = handle_pipe_parent(p, node, env); } else if (node->type == CMD_NODE) - { result = execute_cmd(&node->content.cmd, env); - } else { - printf("Handling unknown node type\n"); - panic("UNREACHABLE"); result = EXIT_FAILURE; + free_node(node); } return (result); } -int eval(t_node *node, t_env **env) +int eval(t_node *node, t_env **env) { return (eval_rec(node, env, STDIN_FILENO)); } @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:03 by dkaiser #+# #+# */ -/* Updated: 2024/12/17 19:26:42 by chuhlig ### ########.fr */ +/* Updated: 2025/01/22 01:49:12 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,13 +14,18 @@ int main(int argc, char *argv[], char *envp[]) { - t_env *env; + t_env *env; + static int promptflag; env = NULL; + promptflag = 0; if (!argc && !argv) return (1); if (init()) return (1); getenvlst(&env, envp); - repl("Minishell $ ", &env); + set_return_code(0, &env); + repl("Minishell $ ", &env, &promptflag); + free_envlst(&env); + return (0); } diff --git a/src/new_node.c b/src/new_node.c index c58d291..b2ab7ea 100644 --- a/src/new_node.c +++ b/src/new_node.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* new_node.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:21:03 by dkaiser #+# #+# */ -/* Updated: 2024/09/17 18:46:35 by dkaiser ### ########.fr */ +/* Updated: 2025/01/20 17:59:01 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,8 @@ t_node *new_pipe_node(t_node *left, t_node *right) return (node); } -t_node *new_cmd_node(char **args, t_redirection redirs[2]) +t_node *new_cmd_node(char **args, t_redirection redirs[2], + t_list *create_files) { t_node *node; @@ -49,7 +50,9 @@ t_node *new_cmd_node(char **args, t_redirection redirs[2]) { node->content.cmd.redirs[0] = redirs[0]; node->content.cmd.redirs[1] = redirs[1]; + node->content.cmd.create_files = create_files; free(redirs); + redirs = NULL; return (node); } return (NULL); diff --git a/src/new_token.c b/src/new_token.c index 92ff421..6f49681 100644 --- a/src/new_token.c +++ b/src/new_token.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* new_token.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 14:29:44 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 14:59:34 by dkaiser ### ########.fr */ +/* Updated: 2025/01/22 00:41:47 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,10 @@ t_token *new_str_token(char *str, t_token *previous, t_token *next) token = new_token(STRING_TOKEN, previous, next); if (token == NULL) + { + free(str); return (NULL); + } token->content.string = str; return (token); } diff --git a/src/parse_cmd.c b/src/parse_cmd.c index 3c4eb96..c0a9ad9 100644 --- a/src/parse_cmd.c +++ b/src/parse_cmd.c @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/08 15:06:25 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 16:04:50 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 21:27:29 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,8 +18,10 @@ t_node *parse_cmd(t_token *tokens, t_env **env) { char **args; t_redirection *redirs; + t_list *create_files; - redirs = collect_redirs(&tokens); + create_files = NULL; + redirs = collect_redirs(&tokens, *env, &create_files); if (redirs == NULL) return (NULL); args = collect_args(&tokens, env); @@ -28,7 +30,7 @@ t_node *parse_cmd(t_token *tokens, t_env **env) free(redirs); return (NULL); } - return (new_cmd_node(args, redirs)); + return (new_cmd_node(args, redirs, create_files)); } static char **collect_args(t_token **tokens, t_env **env) @@ -36,6 +38,7 @@ static char **collect_args(t_token **tokens, t_env **env) t_token *cur; char **result; int i; + t_token *next; cur = *tokens; i = 0; @@ -48,11 +51,14 @@ static char **collect_args(t_token **tokens, t_env **env) i = 0; while (cur != NULL && cur->type == STRING_TOKEN) { + next = cur->next; if (cur->previous) free_token(cur->previous); - result[i] = format_string(cur->content.string, *env); + result[i] = format_string(cur->content.string, *env, ft_atoi("0")); i++; - cur = cur->next; + if (cur->next == NULL) + free_token(cur); + cur = next; } result[i] = NULL; return (result); diff --git a/src/parser.c b/src/parser.c index 1375954..e7b53c2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -6,7 +6,7 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/29 15:53:29 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 16:06:54 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 21:27:15 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,7 @@ static t_token *find_token_by_type(t_token *tokens, int type); t_token *split_at_first(t_token **tokens, int type); static t_node *parse_statement(t_token *tokens, t_env **env); -t_list *parse(t_token *tokens, t_env **env) +t_node *parse(t_token *tokens, t_env **env) { t_node *result; @@ -29,7 +29,7 @@ t_list *parse(t_token *tokens, t_env **env) result = parse_statement(tokens, env); if (result == NULL) printf("Parsing error.\n"); - return (ft_lstnew(result)); + return (result); } static t_node *parse_statement(t_token *tokens, t_env **env) @@ -40,6 +40,7 @@ static t_node *parse_statement(t_token *tokens, t_env **env) if (left_side_tokens == NULL) { free_tokens(tokens); + tokens = NULL; return (NULL); } else if (tokens != NULL) @@ -70,6 +71,7 @@ t_token *split_at_first(t_token **tokens, int type) if (result == split) result = NULL; free_token(split); + split = NULL; return (result); } diff --git a/src/praise_the_norme.c b/src/praise_the_norme.c new file mode 100644 index 0000000..a22843b --- /dev/null +++ b/src/praise_the_norme.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* praise_the_norme.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/20 18:35:41 by dkaiser #+# #+# */ +/* Updated: 2025/01/20 18:39:31 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void i_love_the_norme(t_token **cur, t_token **tokens) +{ + t_token *next_token; + + next_token = (*cur)->next; + free_token_and_connect(*cur); + if (next_token) + { + if (next_token->previous == NULL) + *tokens = next_token->next; + *cur = next_token->next; + free_token_and_connect(next_token); + } + else + *cur = NULL; +} diff --git a/src/read_heredoc.c b/src/read_heredoc.c new file mode 100644 index 0000000..53633e8 --- /dev/null +++ b/src/read_heredoc.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* read_heredoc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/15 18:22:09 by dkaiser #+# #+# */ +/* Updated: 2025/01/15 19:08:07 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include <errno.h> +#include <stdio.h> +#include <sys/errno.h> + +static char *concat_str(char *temp, char *line); +static char *get_result(char *temp, char *result, char *line); +static void *print_error_and_free(char *result); + +char *read_heredoc(char *delimiter) +{ + char *line; + char *result; + char *temp; + size_t total_length; + size_t line_length; + + total_length = 0; + result = NULL; + while (1) + { + line = readline("> "); + if (!line || ft_strcmp(line, delimiter) == 0) + { + free(line); + break ; + } + line_length = ft_strlen(line) + 1; + temp = malloc(total_length + line_length + 1); + if (!temp) + return (print_error_and_free(result)); + result = get_result(temp, result, line); + total_length += line_length; + } + return (result); +} + +static char *concat_str(char *temp, char *line) +{ + ft_strcat(temp, line); + ft_strcat(temp, "\n"); + free(line); + return (temp); +} + +static char *get_result(char *temp, char *result, char *line) +{ + if (result) + { + ft_strcpy(temp, result); + free(result); + } + else + temp[0] = '\0'; + return (concat_str(temp, line)); +} + +static void *print_error_and_free(char *result) +{ + errno = ENOMEM; + perror("heredoc"); + free(result); + return (NULL); +} @@ -6,56 +6,44 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 16:07:04 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 16:01:44 by chuhlig ### ########.fr */ +/* Updated: 2025/01/21 21:29:16 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/minishell.h" #include "token.h" -t_token *reverse_token_list(t_token *head) +void free_repl(char *input, t_node *ast) { - t_token *prev; - t_token *current; - t_token *next; - - prev = NULL; - current = head; - next = NULL; - while (current != NULL) - { - next = current->previous; - current->next = prev; - current->previous = next; - prev = current; - current = next; - } - return (prev); + free(input); + free_node(ast); } -void repl(const char *prompt, t_env **env) +void repl(const char *prompt, t_env **env, int *promptflag) { char *input; t_token *token_list; - t_list *lines; + t_node *ast; + (*promptflag)++; while (1) { input = readline(prompt); if (input == NULL) - return ; + { + if (*promptflag > 1) + (*promptflag)--; + printf("exit\n"); + break ; + } if (input[0] == '\0') continue ; add_history(input); token_list = NULL; tokenizer(input, &token_list, '\0'); - token_list = reverse_token_list(token_list); - lines = parse(token_list, env); - if (lines) - { - print_ast(lines->content); - eval(lines->content, env); - } - free(input); + ast = parse(token_list, env); + if (ast) + set_return_code(eval(ast, env), env); + free_repl(input, ast); } } diff --git a/src/signal_handling.c b/src/signal_handling.c index a19fa94..6c6ca1e 100644 --- a/src/signal_handling.c +++ b/src/signal_handling.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* signal_handling.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 15:08:43 by dkaiser #+# #+# */ -/* Updated: 2024/06/25 13:33:26 by dkaiser ### ########.fr */ +/* Updated: 2025/01/20 12:15:32 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/tokenizer.c b/src/tokenizer.c index 26edd2e..451fa50 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -6,13 +6,33 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/28 20:55:50 by chuhlig #+# #+# */ -/* Updated: 2025/01/11 15:22:07 by chuhlig ### ########.fr */ +/* Updated: 2025/01/22 00:49:10 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" #include "token.h" +t_token *reverse_token_list(t_token *head) +{ + t_token *prev; + t_token *current; + t_token *next; + + prev = NULL; + current = head; + next = NULL; + while (current != NULL) + { + next = current->previous; + current->next = prev; + current->previous = next; + prev = current; + current = next; + } + return (prev); +} + void print_token(t_token *token) { if (DEBUG) @@ -77,11 +97,11 @@ void handle_special_chars(char *s, int *i, int *start, t_token **token_list) *token_list = new_token(PIPE_TOKEN, *token_list, NULL); else if (s[*i] == '\n') *token_list = new_token(NEWLINE_TOKEN, *token_list, NULL); - print_token(*token_list); if (s[*i] == '<' && s[*i + 1] == '<') (*i)++; if (s[*i] == '>' && s[*i + 1] == '>') (*i)++; + print_token(*token_list); *start = *i + 1; } @@ -111,4 +131,5 @@ void tokenizer(char *s, t_token **token_list, char quote_check) pos = i + 1; } } + *token_list = reverse_token_list(*token_list); } |
