aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtins_part_one.c153
-rw-r--r--src/builtins_part_three.c85
-rw-r--r--src/builtins_part_two.c39
-rw-r--r--src/collect_redirs.c147
-rw-r--r--src/create_files.c65
-rw-r--r--src/debug_tools.c6
-rw-r--r--src/env.c25
-rw-r--r--src/env_to_strlst.c28
-rw-r--r--src/env_tools.c21
-rw-r--r--src/error.c30
-rw-r--r--src/execute_cmd.c110
-rw-r--r--src/format_string.c118
-rw-r--r--src/free_node.c79
-rw-r--r--src/free_token.c36
-rw-r--r--src/get_cmd_path.c148
-rw-r--r--src/handle_redir.c103
-rw-r--r--src/init.c4
-rw-r--r--src/interpreter.c137
-rw-r--r--src/main.c11
-rw-r--r--src/new_node.c9
-rw-r--r--src/new_token.c7
-rw-r--r--src/parse_cmd.c16
-rw-r--r--src/parser.c8
-rw-r--r--src/praise_the_norme.c30
-rw-r--r--src/read_heredoc.c76
-rw-r--r--src/repl.c46
-rw-r--r--src/signal_handling.c4
-rw-r--r--src/tokenizer.c25
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)
{
diff --git a/src/env.c b/src/env.c
index 0213209..572040c 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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));
+}
diff --git a/src/init.c b/src/init.c
index fd2c8ac..f41e64a 100644
--- a/src/init.c
+++ b/src/init.c
@@ -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));
}
diff --git a/src/main.c b/src/main.c
index a53760c..e863f3a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
+}
diff --git a/src/repl.c b/src/repl.c
index 7ff80a8..2dcd16d 100644
--- a/src/repl.c
+++ b/src/repl.c
@@ -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);
}