diff options
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/cmd.c | 131 | ||||
| -rw-r--r-- | src/eval/local.c | 2 | ||||
| -rw-r--r-- | src/eval/op.c | 62 | ||||
| -rw-r--r-- | src/eval/redir.c | 27 | ||||
| -rw-r--r-- | src/eval/variable.c | 42 |
5 files changed, 114 insertions, 150 deletions
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, ¶m, &forked_cmd); - g_last_status_code = ret; + status = fork_wrap(fds, ¶m, &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, ¶m, wrapped_eval)); + param.ast = ast; + return (fork_wrap(fds, ¶m, 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) -{ - char *key; - t_tok_lst *value_tokens; - char **strs; - - if (*argv == NULL || !((*argv)->tag & TAG_STR) - || !utils_start_with_valid_identifier((*argv)->content)) - return (true); - - key = (*argv)->content; - (*argv)->content = ft_strchr(key, '='); - *(*argv)->content = '\0'; - (*argv)->content++; - (*argv)->content = ft_strdup((*argv)->content); - - /* printf("|%s| |%s|\n", key, (*argv)->content); */ - /* if (*(*argv)->content == '\0') */ - /* { */ - /* ft_lstpop_front((t_ftlst**)argv, NULL); */ - /* return (true); */ - /* } */ - value_tokens = tok_lst_take_sticked(argv); - strs = preprocess(&value_tokens, env); - if (env_export(env_local, key, strs[0]) == NULL) - return (false); - return (variable_extract(argv, env, env_local)); -} |
