From 9fabc25a980550afc6337fd729632462f2680daa Mon Sep 17 00:00:00 2001 From: Charles Date: Sun, 12 Apr 2020 18:36:17 +0200 Subject: Removing data name in ast union, io_frame, root line ast tag --- README.md | 4 +- include/ast.h | 19 +++--- include/eval.h | 23 ++++--- src/ast.c | 16 ++--- src/eval/eval.c | 194 +++++++++++++++++++++++++------------------------------ src/preprocess.c | 2 +- 6 files changed, 123 insertions(+), 135 deletions(-) diff --git a/README.md b/README.md index 4ab2ad4..7a82c5d 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ You can then read the man pages in ./doc/man or open ./doc/html/index.html in yo ### Mandatory - [ ] Show a prompt when waiting for a new command -- [ ] Search and launch the right executable (based on the *PATH* variable or by using relative or absolute path) like in bash @HappyTramp -- [ ] It must implement the builtins like in bash: @nass1pro +- [x] Search and launch the right executable (based on the *PATH* variable or by using relative or absolute path) like in bash +- [ ] It must implement the builtins like in bash: - [ ] `echo` with option `-n` - [ ] `cd` without `-` option - [ ] `pwd` without any options diff --git a/include/ast.h b/include/ast.h index 6470a17..b725c8b 100644 --- a/include/ast.h +++ b/include/ast.h @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:38 by charles #+# #+# */ -/* Updated: 2020/04/02 13:27:59 by charles ### ########.fr */ +/* Updated: 2020/05/04 11:59:43 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,10 +25,10 @@ /* ** \brief Separator type -** \param SEP_END Regular command end `;` -** \param SEP_PIPE Pipe output of left to right `|` -** \param SEP_AND Execute right if left status == 0 `&&` -** \param SEP_OR Execute right if left status != 0 `||` +** \param SEP_END `;` Regular command end +** \param SEP_PIPE `|` Pipe output of left to right +** \param SEP_AND `&&` Execute right if left status == 0 +** \param SEP_OR `||` Execute right if left status != 0 */ typedef enum e_sep @@ -76,22 +76,19 @@ typedef struct s_cmd ** \brief AST node tag (type) ** \param TAG_CMD Command AST node ** \param TAG_LINE Line AST node -** \param TAG_ROOT Root line AST node */ typedef enum e_ast_tag { TAG_CMD, TAG_LINE, - TAG_ROOT, } t_ast_tag; /* ** \brief AST node struct ** \param tag Node tag -** \param data Union containning possible node data -** \param data::cmd Command struct -** \param data::line Line struct +** \param cmd Command struct +** \param line Line struct */ typedef struct s_ast @@ -101,7 +98,7 @@ typedef struct s_ast { t_line line; t_cmd cmd; - } data; + } ; } t_ast; t_ast *ast_new(t_ast_tag tag, void *data); diff --git a/include/eval.h b/include/eval.h index 31f79c2..fc149b2 100644 --- a/include/eval.h +++ b/include/eval.h @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:30 by charles #+# #+# */ -/* Updated: 2020/04/02 15:38:11 by charles ### ########.fr */ +/* Updated: 2020/05/04 11:58:16 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,8 +27,7 @@ typedef struct { - int pipe_in[2]; - int pipe_out[2]; + int p[2]; t_path path; t_env env; } t_eval_state; @@ -45,15 +44,24 @@ typedef struct s_eval_status typedef struct { - int pipe_in[2]; - int pipe_out[2]; -} t_io_frame; + t_eval_state *state; + t_line *line; + int fd_in; + int fd_out; +} t_fork_param_line; + +typedef struct +{ + char *exec_path; + char **argv; + char **envp; +} t_fork_param_execve; /* ** eval.c */ -int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast); +int eval(int fd_in, int fd_out, t_eval_state *state, t_ast *ast); /* ** exec.c @@ -69,6 +77,5 @@ char *exec_search_path(t_path path, char *path_var, char *exec_name); int pipe_setup_parent(t_cmd *cmd, int pipe_in[2], int pipe_out[2]); int pipe_setup_child(int pipe_in[2], int pipe_out[2]); -int io_frame_init(t_io_frame *frame); #endif diff --git a/src/ast.c b/src/ast.c index 2393a95..4c66fa7 100644 --- a/src/ast.c +++ b/src/ast.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:42 by charles #+# #+# */ -/* Updated: 2020/04/01 17:05:44 by charles ### ########.fr */ +/* Updated: 2020/05/04 12:00:20 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,9 +36,9 @@ t_ast *ast_new(t_ast_tag tag, void *data) ft_bzero(ast, sizeof(t_ast)); ast->tag = tag; if (tag == TAG_CMD) - ft_memcpy(&ast->data.cmd, (t_cmd*)data, sizeof(t_cmd)); + ft_memcpy(&ast->cmd, (t_cmd*)data, sizeof(t_cmd)); else if (tag == TAG_LINE) - ft_memcpy(&ast->data.line, (t_line*)data, sizeof(t_line)); + ft_memcpy(&ast->line, (t_line*)data, sizeof(t_line)); return (ast); } @@ -53,14 +53,14 @@ void ast_destroy(t_ast *ast) return ; if (ast->tag == TAG_CMD) { - ft_split_destroy(ast->data.cmd.argv); - free(ast->data.cmd.in); - free(ast->data.cmd.out); + ft_split_destroy(ast->cmd.argv); + free(ast->cmd.in); + free(ast->cmd.out); } else if (ast->tag == TAG_LINE) { - ast_destroy(ast->data.line.left); - ast_destroy(ast->data.line.right); + ast_destroy(ast->line.left); + ast_destroy(ast->line.right); } free(ast); } diff --git a/src/eval/eval.c b/src/eval/eval.c index 0e57f15..0270024 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/04/02 17:08:18 by charles ### ########.fr */ +/* Updated: 2020/05/04 12:00:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,70 +17,19 @@ #include "eval.h" -#define PARAM_SIZE 3 - -#define PARAM_STATE 0 -#define PARAM_LINE 1 - -#define PARAM_EXEC_PATH 0 -#define PARAM_ARGV 1 -#define PARAM_ENVP 2 - -int io_frame_init(t_io_frame *frame) -{ - if (pipe(frame->pipe_in) == -1 - || pipe(frame->pipe_out) == -1) - return (-1); - /* frame->pipe_in[PIPE_READ] = STDIN_FILENO; */ - /* frame->pipe_in[PIPE_WRITE] = PIPE_CLOSED; */ - /* frame->pipe_out[PIPE_READ] = PIPE_CLOSED; */ - /* frame->pipe_out[PIPE_WRITE] = STDOUT_FILENO; */ - return (0); -} - -static int eval_root(void *params[PARAM_SIZE]) -{ - int status; - t_eval_state *state; - t_line *line; - t_io_frame frame_left; - t_io_frame frame_right; - - state = params[PARAM_STATE]; - line = params[PARAM_LINE]; - io_frame_init(&frame_left); - if (line->right == NULL) - return (eval(&frame_left, state, line->left)); - - if (line->sep == SEP_PIPE) - dup2(STDOUT_FILENO, frame_left.pipe_out[PIPE_WRITE]); - - if ((status = eval(&frame_left, state, line->left)) == -1) - return (-1); - if ((line->sep == SEP_AND && status != 0) || - (line->sep == SEP_OR && status == 0)) - return (status); - - if (line->sep == SEP_PIPE) - dup2(frame_right.pipe_in[PIPE_WRITE], frame_left.pipe_out[PIPE_READ]); - - return (eval(&frame_right, state, line->right)); -} - -int execve_wrapper(void *params[PARAM_SIZE]) -{ - return (execve( - params[PARAM_EXEC_PATH], - params[PARAM_ARGV], - params[PARAM_ENVP] - )); -} +/* +** \brief Wrap a function in a fork +** \param fd_in fork input file descriptor +** \param fd_out fork output file descriptor +** \param passed param of the wrapped function +** \param wrapped function to wrap +*/ -int exec_wrap( - t_io_frame *frame, - void *passed[PARAM_SIZE], - int (*wrapped)(void *params[PARAM_SIZE]) -) +int fork_wrap( + int fd_in, + int fd_out, + void *passed, + int (*wrapped)(void *param)) { int status; pid_t child_pid; @@ -89,8 +38,8 @@ int exec_wrap( return (-1); if (child_pid == 0) { - if (dup2(STDIN_FILENO, frame->pipe_in[PIPE_READ]) == -1 || - dup2(STDOUT_FILENO, frame->pipe_out[PIPE_WRITE]) == -1) + if (dup2(STDIN_FILENO, fd_in) == -1 || + dup2(STDOUT_FILENO, fd_out) == -1) exit(EXIT_FAILURE); if ((status = wrapped(passed)) == -1) exit(EXIT_FAILURE); @@ -100,25 +49,24 @@ int exec_wrap( return (WEXITSTATUS(child_pid)); } -/* -** \brief Evaluate a line -** \param state State of the evaluation -** \param line Line to evaluate -** \return Last Executed command status or -1 on error -*/ - -static int eval_line(t_io_frame *frame, t_eval_state *state, t_line *line) +int run_builtin(t_eval_state *state, char **argv) { - void *params[PARAM_SIZE]; - - params[PARAM_STATE] = state; - params[PARAM_LINE] = line; - return (exec_wrap(frame, params, &eval_root)); + return (builtin_dispatch_run(argv, state->env)); } -int run_builtin(t_eval_state *state, char **argv) +/* +** \brief execve syscall wrapper passed it to fork_wrap +** \param param function params +** \return execve return value +*/ + +int execve_wrapper(void *param) { - return (builtin_dispatch_run(argv, state->env)); + return (execve( + ((t_fork_param_execve*)param)->exec_path, + ((t_fork_param_execve*)param)->argv, + ((t_fork_param_execve*)param)->envp + )); } /* @@ -128,49 +76,85 @@ int run_builtin(t_eval_state *state, char **argv) ** \return Executable status or -1 on error */ -static int eval_cmd(t_io_frame *frame, t_eval_state *state, t_cmd *cmd) +static int eval_cmd(int fd_in, int fd_out, t_eval_state *state, t_cmd *cmd) { - void *params[PARAM_SIZE]; + t_fork_param_execve param; if (builtin_check_exec_name(cmd->argv[0])) return (run_builtin(state, cmd->argv)); - params[PARAM_EXEC_PATH] = exec_search_path( + param.exec_path = exec_search_path( state->path, env_search(state->env, "PATH"), cmd->argv[0]); - if (params[PARAM_EXEC_PATH] == NULL) + if (param.exec_path == NULL) + return (-1); + if (cmd->in != NULL && (fd_in = open(cmd->in, O_RDONLY)) == -1) + return (-1); + if (cmd->out != NULL && (fd_out = open(cmd->out, + (cmd->is_append ? O_APPEND : O_RDONLY) | O_CREAT)) == -1) return (-1); - if (cmd->in != NULL) - if ((frame->pipe_in[PIPE_WRITE] = open(cmd->in, O_RDONLY)) == -1) - return (-1); - if (cmd->out != NULL) - if ((frame->pipe_out[PIPE_READ] = open(cmd->out, - (cmd->is_append ? O_APPEND : O_RDONLY) | O_CREAT)) == -1) - return (-1); - params[PARAM_ARGV] = cmd->argv; - params[PARAM_ENVP] = state->env->data; - return (exec_wrap(frame, params, &execve_wrapper)); + param.argv = cmd->argv; + param.envp = (char**)state->env->data; + return (fork_wrap(fd_in, fd_out, ¶m, &execve_wrapper)); +} + +/* +** \brief Evaluate a line +** \param state State of the evaluation +** \param line Line to evaluate +** \return Last Executed command status or -1 on error +*/ +static int eval_line(void *param) +{ + int status; + t_eval_state *state; + t_line *line; + int fd_in; + int fd_out; + + state = ((t_fork_param_line*)param)->state; + line = ((t_fork_param_line*)param)->line; + fd_in = ((t_fork_param_line*)param)->fd_in; + fd_out = ((t_fork_param_line*)param)->fd_out; + + /* if (line->right == NULL) */ + /* return (eval(state, line->left)); */ + + /* if (line->sep == SEP_PIPE) */ + /* pipe(state->p); */ + + if (line->left->tag == TAG_LINE) + { + return (fork_wrap(fd_in, fd_out, param, &eval_line)); + } + if ((status = eval(fd_in, fd_out, state, line->left)) == -1) + return (-1); + if ((line->sep == SEP_AND && status != 0) || + (line->sep == SEP_OR && status == 0)) + return (status); + + return (eval(fd_in, fd_out, state, line->right)); } /* ** \brief Evaluate an AST ** \param state State of the evaluation ** \param ast Abstract syntax tree to evaluate -** \return Executable status or -1 on error +** \return Last command status or -1 on error */ -int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast) +int eval(int fd_in, int fd_out, t_eval_state *state, t_ast *ast) { - void *params[PARAM_SIZE]; + t_fork_param_line param; errno = 0; - if (ast->tag == TAG_ROOT) + if (ast->tag == TAG_LINE) { - params[PARAM_STATE] = state; - params[PARAM_LINE] = &ast->data.line; - return (eval_root(params)); + param.state = state; + param.line = &ast->line; + param.fd_in = fd_in; + param.fd_out = fd_out; + return (eval_line(¶m)); } - if (ast->tag == TAG_LINE) - return (eval_line(frame, state, &ast->data.line)); if (ast->tag == TAG_CMD) - return (eval_cmd(frame, state, &ast->data.cmd)); + return (eval_cmd(fd_in, fd_out, state, &ast->cmd)); return (-1); } diff --git a/src/preprocess.c b/src/preprocess.c index 1151bca..c30bb70 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/04/05 14:58:00 by charles ### ########.fr */ +/* Updated: 2020/04/05 15:04:06 by charles ### ########.fr */ /* */ /* ************************************************************************** */ -- cgit