aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/error.h13
-rw-r--r--include/eval.h46
-rw-r--r--include/lexer.h32
-rw-r--r--include/minishell.h2
-rw-r--r--src/builtin/cd.c23
-rw-r--r--src/builtin/echo.c2
-rw-r--r--src/builtin/exit.c14
-rw-r--r--src/builtin/export.c16
-rw-r--r--src/builtin/unset.c6
-rw-r--r--src/env.c4
-rw-r--r--src/error.c24
-rw-r--r--src/eval/cmd.c131
-rw-r--r--src/eval/local.c2
-rw-r--r--src/eval/op.c62
-rw-r--r--src/eval/redir.c27
-rw-r--r--src/eval/variable.c42
-rw-r--r--src/lexer/lexer.c4
-rw-r--r--src/lexer/tok_lst.c20
-rw-r--r--src/main.c28
-rw-r--r--src/parser/parsed.c6
-rw-r--r--src/signal.c4
-rw-r--r--src/utils.c2
22 files changed, 240 insertions, 270 deletions
diff --git a/include/error.h b/include/error.h
index 941f1b2..3933fe9 100644
--- a/include/error.h
+++ b/include/error.h
@@ -6,7 +6,7 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/08/27 20:34:25 by charles #+# #+# */
-/* Updated: 2020/08/27 20:38:52 by charles ### ########.fr */
+/* Updated: 2020/09/10 20:29:17 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,17 +20,10 @@
** error.c
*/
-typedef enum
-{
- ERR_FATAL = -1,
- ERR_NONE = 0,
- ERR_AMBIGUOUS_REDIR = 1,
- ERR_OPEN = 1,
- ERR_CMD_NOT_FOUND = 127,
- ERR_SYNTAX = 2,
-} t_err;
+# define EVAL_FATAL 1024
void errorf(const char *format, ...);
void verrorf(const char *format, va_list ap);
+int errorf_ret(int err, const char *format, ...);
#endif
diff --git a/include/eval.h b/include/eval.h
index a23b249..89f05ef 100644
--- a/include/eval.h
+++ b/include/eval.h
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:05:30 by charles #+# #+# */
-/* Updated: 2020/09/09 17:27:21 by charles ### ########.fr */
+/* Updated: 2020/09/12 12:28:36 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,60 +24,54 @@
typedef struct
{
- t_path path;
- t_env env;
- t_ast *ast;
- int fds[2];
-} t_fork_param_parent;
+ t_path path;
+ t_env env;
+ t_ast *ast;
+ int fds[2];
+} t_fork_param_args;
typedef struct
{
char *exec_path;
char **argv;
t_env env;
- t_env env_local;
t_builtin_entry *builtin;
} t_fork_param_cmd;
-# define MS_NO_FD -2
-# define FDS_WRITE 1
-# define FDS_READ 0
+# define FD_NONE -2
+# define FD_WRITE 1
+# define FD_READ 0
-extern pid_t g_child_pid;
+extern pid_t g_child_pid;
/*
** op.c
*/
-int eval_op(int fds[2], t_env env, t_path path, t_ast *ast);
-int eval(int fds[2], t_env env, t_path path, t_ast *ast);
+int eval_op(int fds[2], t_env env, t_path path, t_ast *ast);
+int eval(int fds[2], t_env env, t_path path, t_ast *ast);
+int eval_forked(int fds[2], t_env env, t_path path, t_ast *ast, pid_t *child_pid);
/*
** cmd.c
*/
-int fork_wrap(int fds[2], void *passed, int (*wrapped)(void *param));
-int eval_cmd(int fds[2], t_env env, t_path path, t_ast *ast);
-t_ftlst *split_token(t_ftlst **lst, enum e_tok);
+int fork_wrap(int fds[2], void *passed, int (*wrapped)(void *param), pid_t *child_pid);
+int fork_wrap_wait(int fds[2], void *passed, int (*wrapped)(void *param));
+int eval_cmd(int fds[2], t_env env, t_path path, t_ast *ast);
/*
** redir.c
*/
-bool redir_extract(t_tok_lst **redirs, t_env env, int fds[2]);
+int redir_extract(t_tok_lst **redirs, t_env env, int fds[2]);
/*
** exec.c
*/
-bool exec_is_path(char *exec_name);
-bool exec_is_valid(char *exec_path);
-char *exec_search_path(t_path path, char *path_var, char *exec_name);
-
-/*
-** variable.c
-*/
-
-bool variable_extract(t_tok_lst **argv, t_env env, t_env env_local);
+bool exec_is_path(char *exec_name);
+bool exec_is_valid(char *exec_path);
+char *exec_search_path(t_path path, char *path_var, char *exec_name);
#endif
diff --git a/include/lexer.h b/include/lexer.h
index fd8972e..7e1bf06 100644
--- a/include/lexer.h
+++ b/include/lexer.h
@@ -6,7 +6,7 @@
/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/19 10:51:26 by nahaddac #+# #+# */
-/* Updated: 2020/09/10 06:17:43 by nahaddac ### ########.fr */
+/* Updated: 2020/09/11 19:17:06 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,7 +16,26 @@
# include <stdlib.h>
# include "libft_lst.h"
# include "libft_str.h"
-// # include "minishell.h"
+
+/*
+** \brief token tags (type of token)
+** \param TAG_AND &&
+** \param TAG_END ;
+** \param TAG_OR ||
+** \param TAG_PIPE |
+** \param TAG_REDIR_IN <
+** \param TAG_REDIR_OUT >
+** \param TAG_REDIR_APPEND >>
+** \param TAG_PARENT_OPEN (
+** \param TAG_PARENT_CLOSE )
+** \param TAG_STR unquoted string
+** \param TAG_STR_DOUBLE string quoted with "
+** \param TAG_STR_SINGLE string quoted with '
+** \param TAG_STICK token is sticked to the next one
+** \param TAG_IS_STR all of string tags
+** \param TAG_IS_REDIR all of redirection tags
+** \param TAG_IS_SEP all of separator tags
+*/
enum e_tok
{
@@ -44,7 +63,13 @@ enum e_tok
*/
/*
-** \warning DO NOT change the order of the fields
+** \brief Token list struct
+** \param content token string content
+** \param next next token in the list (NULL if end)
+** \param tag token tag
+** \warning DO NOT change the order of the fields
+** (they are in the same order as t_ftlst so
+** that t_ftlst functions can be used on this struct aswell)
*/
typedef struct s_tok_lst
@@ -61,7 +86,6 @@ t_tok_lst *tok_lst_push_front(t_tok_lst **tokens, t_tok_lst *pushed);
void *tok_lst_destroy(t_tok_lst **tokens, void (*del)(void*));
t_tok_lst *tok_lst_last(t_tok_lst *tokens);
t_tok_lst *tok_lst_uncons(t_tok_lst **tokens);
-t_tok_lst *tok_lst_take_sticked(t_tok_lst **tokens);
/*
** lexer.c
diff --git a/include/minishell.h b/include/minishell.h
index 085f082..7e755a3 100644
--- a/include/minishell.h
+++ b/include/minishell.h
@@ -51,7 +51,7 @@
typedef t_ftht* t_path;
typedef t_ftvec* t_env;
-extern int g_last_status_code;
+extern int g_last_status;
extern char *g_basename;
/*
diff --git a/src/builtin/cd.c b/src/builtin/cd.c
index d7115e5..de1eeb9 100644
--- a/src/builtin/cd.c
+++ b/src/builtin/cd.c
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:10:20 by charles #+# #+# */
-/* Updated: 2020/07/19 19:05:25 by charles ### ########.fr */
+/* Updated: 2020/09/12 11:09:49 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,35 +19,26 @@
int builtin_cd(char **argv, t_env env)
{
- char buf[PATH_MAX];
+ char buf[PATH_MAX + 1];
char *home;
(void)env;
if (argv[1] != NULL && argv[2] != NULL)
- {
- errorf("cd: too many arguments\n");
- return (1);
- }
+ return (errorf_ret(1, "cd: too many arguments\n"));
if (argv[1] != NULL && argv[1][0] == '\0')
return (0);
if (argv[1] == NULL)
{
if ((home = env_search(env, "HOME")) == NULL)
- {
- errorf("cd: HOME not set\n");
- return (1);
- }
+ return (errorf_ret(1, "cd: HOME not set\n"));
argv[1] = home;
}
errno = 0;
if (chdir(argv[1]) == -1)
- {
- errorf("cd: %s: %s\n", argv[1], strerror(errno));
- return (1);
- }
- if (!(getcwd(buf, PATH_MAX)))
+ return (errorf_ret(1, "cd: %s: %s\n", argv[1], strerror(errno)));
+ if (getcwd(buf, PATH_MAX) == NULL)
return (1);
if (env_export(env, "PWD", buf) == NULL)
- return (2); // FIXME malloc error recognition in builtins and cmd
+ return (EVAL_FATAL);
return (0);
}
diff --git a/src/builtin/echo.c b/src/builtin/echo.c
index 75a350c..9ad427a 100644
--- a/src/builtin/echo.c
+++ b/src/builtin/echo.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:10:47 by charles #+# #+# */
-/* Updated: 2020/06/15 14:26:30 by charles ### ########.fr */
+/* Updated: 2020/09/12 15:24:34 by charles ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/builtin/exit.c b/src/builtin/exit.c
index 640fc01..a24efad 100644
--- a/src/builtin/exit.c
+++ b/src/builtin/exit.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:10:16 by charles #+# #+# */
-/* Updated: 2020/08/20 17:31:18 by charles ### ########.fr */
+/* Updated: 2020/09/10 19:41:03 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,7 +24,7 @@ int builtin_exit(char **argv, t_env env)
(void)env;
if (argv[1] == NULL)
- status = g_last_status_code;
+ status = g_last_status;
else
{
errno = 0;
@@ -32,15 +32,9 @@ int builtin_exit(char **argv, t_env env)
while (ft_isblank(*after))
after++;
if (*after != '\0' || errno == ERANGE)
- {
- errorf("exit: %s: numeric argument required\n", argv[1]);
- return (2);
- }
+ return (errorf_ret(2, "exit: %s: numeric argument required\n", argv[1]));
if (argv[2] != NULL)
- {
- errorf("exit: too many arguments\n");
- return (1);
- }
+ return (errorf_ret(1, "exit: too many arguments\n"));
}
exit(status % 256);
return (0);
diff --git a/src/builtin/export.c b/src/builtin/export.c
index e19756d..d394af6 100644
--- a/src/builtin/export.c
+++ b/src/builtin/export.c
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:11:34 by charles #+# #+# */
-/* Updated: 2020/08/28 17:49:47 by charles ### ########.fr */
+/* Updated: 2020/09/12 11:06:47 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,16 +21,20 @@ static void st_put_declare_x(char *s)
{
char *equal_ptr;
- // could use errorf on stdout
if (s == NULL)
return ;
- ft_putstr("declare -x ");
+ ft_putstr("export ");
if ((equal_ptr = ft_strchr(s, '=')) == NULL)
equal_ptr = ft_strchr(s, '\0');
write(STDOUT_FILENO, s, equal_ptr - s);
ft_putchar('=');
ft_putchar('"');
- ft_putstr(equal_ptr + 1);
+ while (*++equal_ptr != '\0')
+ {
+ if (*equal_ptr == '"')
+ ft_putchar('\\');
+ ft_putchar(*equal_ptr);
+ }
ft_putchar('"');
ft_putchar('\n');
}
@@ -38,7 +42,7 @@ static void st_put_declare_x(char *s)
int builtin_export(char **argv, t_env env)
{
int status;
- size_t i;
+ size_t i;
char *equal_ptr;
if (argv[1] == NULL)
@@ -62,7 +66,7 @@ int builtin_export(char **argv, t_env env)
continue;
}
if (env_export(env, argv[i], equal_ptr == NULL ? "" : equal_ptr + 1) == NULL)
- return (127); // malloc error
+ return (EVAL_FATAL);
}
return (status);
}
diff --git a/src/builtin/unset.c b/src/builtin/unset.c
index 367f063..30facd3 100644
--- a/src/builtin/unset.c
+++ b/src/builtin/unset.c
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:10:51 by charles #+# #+# */
-/* Updated: 2020/07/19 18:47:36 by charles ### ########.fr */
+/* Updated: 2020/09/10 13:49:58 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -31,11 +31,11 @@ int builtin_unset(char **argv, t_env env)
{
errorf("unset: `%s': not a valid identifier\n", argv[i]);
status = 1;
- continue; // put invalid identifier
+ continue ;
}
found_index = env_search_index(env, argv[i]);
if (found_index == -1)
- continue;
+ continue ;
ft_vecremove(env, found_index, free);
}
return (status);
diff --git a/src/env.c b/src/env.c
index 1766a50..19ead42 100644
--- a/src/env.c
+++ b/src/env.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */
-/* Updated: 2020/09/09 16:56:39 by charles ### ########.fr */
+/* Updated: 2020/09/10 14:19:42 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -105,7 +105,7 @@ char *env_search_first_match(t_env env, const char *haystack)
while (ft_isalnum(haystack[len]) || haystack[len] == '_')
len++;
if (haystack[0] == '?')
- return (ft_itoa(g_last_status_code)); // FIXME leak (static buffer)
+ return (ft_itoa(g_last_status)); // FIXME leak (static buffer)
if (len == 0)
return (NULL);
i = -1;
diff --git a/src/error.c b/src/error.c
index e19a9ed..2e56117 100644
--- a/src/error.c
+++ b/src/error.c
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/14 11:02:52 by charles #+# #+# */
-/* Updated: 2020/08/27 10:44:08 by charles ### ########.fr */
+/* Updated: 2020/09/10 20:29:41 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,7 +19,7 @@
** \note NULL arguments are ignored
*/
-void errorf(const char *format, ...)
+void errorf(const char *format, ...)
{
va_list ap;
@@ -28,7 +28,11 @@ void errorf(const char *format, ...)
va_end(ap);
}
-void verrorf(const char *format, va_list ap)
+/*
+** \brief errorf with an argument pointer (ap) instead of arguments
+*/
+
+void verrorf(const char *format, va_list ap)
{
char *arg;
@@ -49,3 +53,17 @@ void verrorf(const char *format, va_list ap)
}
}
}
+
+/*
+** \brief errorf helper to return an status code and print the error
+*/
+
+int errorf_ret(int status, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ verrorf(format, ap);
+ va_end(ap);
+ return (status);
+}
diff --git a/src/eval/cmd.c b/src/eval/cmd.c
index 5130a45..9745632 100644
--- a/src/eval/cmd.c
+++ b/src/eval/cmd.c
@@ -6,14 +6,15 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/14 10:41:31 by charles #+# #+# */
-/* Updated: 2020/09/09 17:40:54 by charles ### ########.fr */
+/* Updated: 2020/09/12 17:04:23 by charles ### ########.fr */
/* */
/* ************************************************************************** */
#include "eval.h"
pid_t g_child_pid = -1;
-int g_last_status_code = 0;
+int g_last_status = 0;
+
void token_debug(void *v);
/*
@@ -25,66 +26,73 @@ void token_debug(void *v);
*/
int fork_wrap(
- int fds[2],
- void *passed,
- int (*wrapped)(void *param))
+ int fds[2],
+ void *passed,
+ int (*wrapped)(void *param),
+ pid_t *child_pid
+)
{
int status;
- pid_t child_pid;
+ bool waiting;
+ pid_t pid;
- if ((child_pid = fork()) == -1)
- return (-1);
- if (child_pid == 0)
+ waiting = child_pid == NULL;
+ if (waiting)
+ child_pid = &pid;
+ if ((*child_pid = fork()) == -1)
+ return (EVAL_FATAL);
+ if (*child_pid == 0)
{
- if ((fds[FDS_READ] != MS_NO_FD && dup2(fds[FDS_READ], STDIN_FILENO) == -1) ||
- (fds[FDS_WRITE] != MS_NO_FD && dup2(fds[FDS_WRITE], STDOUT_FILENO) == -1))
+ if ((fds[FD_READ] != FD_NONE && dup2(fds[FD_READ], STDIN_FILENO) == -1) ||
+ (fds[FD_WRITE] != FD_NONE && dup2(fds[FD_WRITE], STDOUT_FILENO) == -1))
exit(EXIT_FAILURE);
- if ((status = wrapped(passed)) == -1)
+ if ((status = wrapped(passed)) == EVAL_FATAL) // FIXME detect fatal in child (pipe ?)
exit(EXIT_FAILURE);
exit(status);
}
- g_child_pid = child_pid;
- wait(&child_pid);
- close(fds[FDS_WRITE]);
- // also read end?
- return (WEXITSTATUS(child_pid));
+ g_child_pid = *child_pid;
+ if (waiting)
+ {
+ waitpid(*child_pid, child_pid, 0);
+ close(fds[FD_WRITE]);
+ /* close(fds[FD_READ]); */
+ return (WEXITSTATUS(*child_pid));
+ }
+ return (0);
}
int forked_cmd(void *void_param)
{
t_fork_param_cmd *param;
- int ret;
+ int status;
+ struct stat statbuf;
param = void_param;
- ft_vecpop(param->env_local, NULL);
- if (ft_vecswallow_at(param->env, param->env->size - 1, param->env_local) == NULL)
- {
- ft_vecdestroy(param->env_local, free);
- return (-1);
- }
+ /* ft_vecpop(param->env_local, NULL); */
+ /* if (ft_vecswallow_at(param->env, param->env->size - 1, param->env_local) == NULL) */
+ /* { */
+ /* ft_vecdestroy(param->env_local, free); */
+ /* return (EVAL_FATAL); */
+ /* } */
if (param->builtin != NULL)
return (param->builtin->func(param->argv, param->env));
else
{
+ if (stat(param->exec_path, &statbuf) == -1)
+ return (errorf_ret(126, "%s: %s\n", param->exec_path, strerror(errno)));
+ if (S_ISDIR(statbuf.st_mode))
+ return (errorf_ret(126, "%s: Is a directory\n", param->exec_path));
+ if (!(statbuf.st_mode & 0444))
+ return (errorf_ret(126, "%s: %s\n", param->exec_path, strerror(EACCES)));
errno = 0;
- ret = execve(param->exec_path, param->argv, (char**)param->env->data);
- if (ret == -1)
+ status = execve(param->exec_path, param->argv, (char**)param->env->data);
+ if (status == -1)
{
if (errno == ENOEXEC)
return (0);
- struct stat statbuf;
- if (stat(param->exec_path, &statbuf) != -1 && S_ISDIR(statbuf.st_mode))
- {
- errorf("%s: Is a directory\n", param->exec_path);
- ret = 126;
- }
- else
- {
- errorf("%s: %s\n", param->exec_path, strerror(errno));
- ret = 126;
- }
+ return (errorf_ret(126, "%s: %s\n", param->exec_path, strerror(errno)));
}
- return (ret);
+ return (status);
}
}
@@ -92,66 +100,37 @@ int eval_cmd(int fds[2], t_env env, t_path path, t_ast *ast)
{
t_fork_param_cmd param;
char **argv;
+ int status;
- if (!redir_extract(&ast->redirs, env, fds))
- {
- ast->redirs = NULL;
- return (-1);
- }
- ast->redirs = NULL;
- if ((param.env_local = env_from_array((char*[]){NULL})) == NULL)
- return (-1);
- variable_extract(&ast->cmd_argv, env, param.env_local);
-
- /* char **strs = preprocess(&start, env); */
- /* */
- /* if (env_export(env_local, id, strs[0]) == NULL) */
- /* return (-1); */
- /* if (ast->cmd_argv == NULL) // FIXME special env not passed to child processes */
- /* { */
- /* ft_vecpop(param.env_local, NULL); */
- /* if (ft_vecswallow_at(env, env->size - 1, param.env_local) == NULL) */
- /* { */
- /* ft_vecdestroy(param.env_local, free); */
- /* return (-1); */
- /* } */
- /* g_last_status_code = 0; */
- /* return (0); */
- /* } */
+ if ((status = redir_extract(&ast->redirs, env, fds)) != 0)
+ return (status);
if ((argv = preprocess(&ast->cmd_argv, env)) == NULL)
{
ast->cmd_argv = NULL;
- return (-1);
+ return (EVAL_FATAL);
}
- // can have no command (e.g `< file`)
if (argv[0] == NULL)
return (0);
param.builtin = builtin_search_func(argv[0]);
if (param.builtin == NULL)
{
- // check env local for PATH
param.exec_path = exec_search_path(path, env_search(env, "PATH"), argv[0]);
if (param.exec_path == NULL)
{
- g_last_status_code = 127;
errorf("%s: command not found\n", argv[0]);
ft_split_destroy(argv);
- return (-1); // return error status
+ return (127);
}
}
else if (!param.builtin->forked)
- {
- g_last_status_code = param.builtin->func(argv, env);
- return (g_last_status_code);
- }
+ return (param.builtin->func(argv, env));
param.argv = argv;
param.env = env;
- int ret = fork_wrap(fds, &param, &forked_cmd);
- g_last_status_code = ret;
+ status = fork_wrap(fds, &param, &forked_cmd, NULL);
ft_split_destroy(argv);
- ft_vecdestroy(param.env_local, free);
- return (ret);
+ g_last_status = status;
+ return (status);
}
diff --git a/src/eval/local.c b/src/eval/local.c
index 13719cd..089a0c7 100644
--- a/src/eval/local.c
+++ b/src/eval/local.c
@@ -62,7 +62,7 @@
/* ft_vecdestroy(param.env_local, free); */
/* return (-1); */
/* } */
- /* g_last_status_code = 0; */
+ /* g_last_status = 0; */
/* return (0); */
/* } */
diff --git a/src/eval/op.c b/src/eval/op.c
index 36340be..a39e380 100644
--- a/src/eval/op.c
+++ b/src/eval/op.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/17 15:27:22 by charles #+# #+# */
-/* Updated: 2020/08/28 16:54:39 by charles ### ########.fr */
+/* Updated: 2020/09/12 17:00:11 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,18 +19,39 @@ int eval_op(int fds[2], t_env env, t_path path, t_ast *ast)
int right_fds[2];
int p[2];
- left_fds[FDS_READ] = fds[FDS_READ];
- left_fds[FDS_WRITE] = MS_NO_FD;
- right_fds[FDS_READ] = MS_NO_FD;
- right_fds[FDS_WRITE] = fds[FDS_WRITE];
+ left_fds[FD_READ] = fds[FD_READ];
+ left_fds[FD_WRITE] = FD_NONE;
+ right_fds[FD_READ] = FD_NONE;
+ right_fds[FD_WRITE] = fds[FD_WRITE];
if (ast->op.sep == TAG_PIPE)
{
pipe(p);
- left_fds[FDS_WRITE] = p[FDS_WRITE];
- right_fds[FDS_READ] = p[FDS_READ];
+ left_fds[FD_WRITE] = p[FD_WRITE];
+ right_fds[FD_READ] = p[FD_READ];
+
+ pid_t left_pid;
+ pid_t right_pid;
+ eval_forked(left_fds, env, path, ast->op.left, &left_pid);
+ eval_forked(right_fds, env, path, ast->op.right, &right_pid);
+
+ pid_t finished;
+ finished = wait(NULL);
+ close(p[FD_READ]);
+ close(p[FD_WRITE]);
+ if (finished == left_pid)
+ {
+ /* waitpid(right_pid, &right_pid, 0); */
+ }
+ else if (finished == right_pid)
+ {
+ kill(left_pid, SIGKILL);
+ /* waitpid(left_pid, &left_pid, 0); */
+ }
+ return (0);
}
- if ((status = eval(left_fds, env, path, ast->op.left)) == -1)
- return (-1);
+ if ((status = eval(left_fds, env, path, ast->op.left)) == EVAL_FATAL)
+ return (EVAL_FATAL);
+ g_last_status = status;
if ((ast->op.sep == TAG_AND && status != 0) ||
(ast->op.sep == TAG_PIPE && status != 0) ||
(ast->op.sep == TAG_OR && status == 0))
@@ -40,7 +61,7 @@ int eval_op(int fds[2], t_env env, t_path path, t_ast *ast)
int wrapped_eval(void *void_param)
{
- t_fork_param_parent *param;
+ t_fork_param_args *param;
param = void_param;
return (eval(param->fds, param->env, param->path, param->ast));
@@ -48,17 +69,24 @@ int wrapped_eval(void *void_param)
int eval_parent(int fds[2], t_env env, t_path path, t_ast *ast)
{
- t_fork_param_parent param;
+ int status;
+
+ if ((status = redir_extract(&ast->redirs, env, fds)) != 0)
+ return (status);
+ ast->tag ^= AST_PARENT;
+ return (eval_forked(fds, env, path, ast->parent_ast, NULL));
+}
+
+int eval_forked(int fds[2], t_env env, t_path path, t_ast *ast, pid_t *child_pid)
+{
+ t_fork_param_args param;
- if (!redir_extract(&ast->redirs, env, fds))
- return (-1);
param.fds[0] = fds[0];
param.fds[1] = fds[1];
param.env = env;
param.path = path;
- ast->tag ^= AST_PARENT;
- param.ast = ast->parent_ast;
- return (fork_wrap(fds, &param, wrapped_eval));
+ param.ast = ast;
+ return (fork_wrap(fds, &param, wrapped_eval, child_pid));
}
int eval(int fds[2], t_env env, t_path path, t_ast *ast)
@@ -69,5 +97,5 @@ int eval(int fds[2], t_env env, t_path path, t_ast *ast)
return (eval_op(fds, env, path, ast));
if (ast->tag == AST_CMD)
return (eval_cmd(fds, env, path, ast));
- return (-1);
+ return (EVAL_FATAL);
}
diff --git a/src/eval/redir.c b/src/eval/redir.c
index e8796a5..39e202d 100644
--- a/src/eval/redir.c
+++ b/src/eval/redir.c
@@ -6,15 +6,15 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/15 11:05:34 by charles #+# #+# */
-/* Updated: 2020/08/28 17:14:19 by charles ### ########.fr */
+/* Updated: 2020/09/10 20:25:59 by charles ### ########.fr */
/* */
/* ************************************************************************** */
#include "eval.h"
-static bool st_open_replace(int *fd, char *filename, int oflag)
+static int st_open_replace(int *fd, char *filename, int oflag)
{
- if (*fd != MS_NO_FD)
+ if (*fd != FD_NONE)
close(*fd);
if (oflag & O_CREAT)
*fd = open(filename, oflag, 0644);
@@ -22,15 +22,14 @@ static bool st_open_replace(int *fd, char *filename, int oflag)
*fd = open(filename, oflag);
if (*fd == -1)
{
- g_last_status_code = 1;
errorf("%s: %s\n", filename, strerror(errno));
free(filename);
- return (false);
+ return (1);
}
- return (true);
+ return (0);
}
-bool redir_extract(
+int redir_extract(
t_tok_lst **redirs,
t_env env,
int fds[2])
@@ -40,10 +39,10 @@ bool redir_extract(
char *filename;
if (*redirs == NULL)
- return (true);
+ return (0);
if (!((*redirs)->tag & TAG_IS_REDIR) || (*redirs)->next == NULL
|| !((*redirs)->next->tag & TAG_IS_STR))
- return (false);
+ return (EVAL_FATAL);
curr = (*redirs)->next;
after = NULL;
while (curr != NULL && curr->tag & TAG_IS_STR)
@@ -59,18 +58,18 @@ bool redir_extract(
{
tok_lst_destroy(redirs, free);
tok_lst_destroy(&after, free);
- return (false);
+ return (EVAL_FATAL);
}
if (((*redirs)->tag == TAG_REDIR_IN
- && !st_open_replace(&fds[FDS_READ], filename, O_RDONLY))
+ && st_open_replace(&fds[FD_READ], filename, O_RDONLY) != 0)
|| ((*redirs)->tag == TAG_REDIR_OUT
- && !st_open_replace(&fds[FDS_WRITE], filename, O_WRONLY | O_CREAT | O_TRUNC))
+ && st_open_replace(&fds[FD_WRITE], filename, O_WRONLY | O_CREAT | O_TRUNC) != 0)
|| ((*redirs)->tag == TAG_REDIR_APPEND
- && !st_open_replace(&fds[FDS_WRITE], filename, O_WRONLY | O_CREAT | O_APPEND)))
+ && st_open_replace(&fds[FD_WRITE], filename, O_WRONLY | O_CREAT | O_APPEND) != 0))
{
tok_lst_destroy(redirs, free);
tok_lst_destroy(&after, free);
- return (false);
+ return (EVAL_FATAL);
}
tok_lst_destroy(redirs, free);
free(filename);
diff --git a/src/eval/variable.c b/src/eval/variable.c
deleted file mode 100644
index 2b6d7cf..0000000
--- a/src/eval/variable.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* variable.c :+: :+: :+: */
-/* +:+ +:+ +:+ */
-/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
-/* +#+#+#+#+#+ +#+ */
-/* Created: 2020/09/09 17:12:14 by charles #+# #+# */
-/* Updated: 2020/09/09 18:22:43 by charles ### ########.fr */
-/* */
-/* ************************************************************************** */
-
-#include "eval.h"
-
-bool variable_extract(t_tok_lst **argv, t_env env, t_env env_local)
-{