diff options
Diffstat (limited to 'src/eval/cmd.c')
| -rw-r--r-- | src/eval/cmd.c | 131 |
1 files changed, 55 insertions, 76 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); } |
