diff options
| -rw-r--r-- | include/ast.h | 4 | ||||
| -rw-r--r-- | include/eval.h | 11 | ||||
| m--------- | libft | 0 | ||||
| -rw-r--r-- | src/builtin/cd.c | 10 | ||||
| -rw-r--r-- | src/builtin/echo.c | 6 | ||||
| -rw-r--r-- | src/builtin/export.c | 4 | ||||
| -rw-r--r-- | src/builtin/unset.c | 5 | ||||
| -rw-r--r-- | src/env.c | 7 | ||||
| -rw-r--r-- | src/eval/eval.c | 160 | ||||
| -rw-r--r-- | src/main.c | 13 | ||||
| -rw-r--r-- | src/path.c | 13 |
11 files changed, 167 insertions, 66 deletions
diff --git a/include/ast.h b/include/ast.h index 0d14779..6470a17 100644 --- a/include/ast.h +++ b/include/ast.h @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:38 by charles #+# #+# */ -/* Updated: 2020/04/01 17:52:43 by charles ### ########.fr */ +/* Updated: 2020/04/02 13:27:59 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -76,12 +76,14 @@ 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; /* diff --git a/include/eval.h b/include/eval.h index 31f729b..31f79c2 100644 --- a/include/eval.h +++ b/include/eval.h @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:30 by charles #+# #+# */ -/* Updated: 2020/04/01 17:53:26 by charles ### ########.fr */ +/* Updated: 2020/04/02 15:38:11 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,11 +43,17 @@ typedef struct s_eval_status int status; } t_eval_status; +typedef struct +{ + int pipe_in[2]; + int pipe_out[2]; +} t_io_frame; + /* ** eval.c */ -int eval(t_eval_state *state, t_ast *ast); +int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast); /* ** exec.c @@ -63,5 +69,6 @@ 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/libft b/libft -Subproject 1925805cc760061d5742f9d215998561fcd4521 +Subproject d2feec1f97e9f8f201e56ad33662bb663c328a0 diff --git a/src/builtin/cd.c b/src/builtin/cd.c index 66f1f81..1a7c70e 100644 --- a/src/builtin/cd.c +++ b/src/builtin/cd.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:20 by charles #+# #+# */ -/* Updated: 2020/04/01 22:15:49 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:33:15 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,14 +19,10 @@ int builtin_cd(char **argv, t_env env) { - char *path; - - path = argv[1]; + (void)env; if (argv[1] == NULL) - path = env_search(env, "HOME"); - if (path == NULL) return (1); - if (chdir(path) == -1) + if (chdir(argv[1]) == -1) return (1); return (0); } diff --git a/src/builtin/echo.c b/src/builtin/echo.c index 9b7a8f6..886c2ca 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/04/01 17:10:48 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:18:16 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,8 +22,8 @@ int builtin_echo(char **argv, t_env env) bool newline; (void)env; - newline = ft_strcmp(argv[1], "-n") == 0; - if (newline) + newline = !ft_strcmp(argv[1], "-n") == 0; + if (!newline) argv++; while (*++argv != NULL) { diff --git a/src/builtin/export.c b/src/builtin/export.c index 650a421..3636407 100644 --- a/src/builtin/export.c +++ b/src/builtin/export.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:11:34 by charles #+# #+# */ -/* Updated: 2020/04/01 22:37:47 by charles ### ########.fr */ +/* Updated: 2020/04/02 10:46:27 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,7 +25,7 @@ int builtin_export(char **argv, t_env env) return (1); if ((tmp = ft_strdup(argv[1])) == NULL) return (2); - if (ft_vecpush(env, tmp) == NULL) + if (ft_vecinsert(env, env->size - 1, tmp) == NULL) return (2); // internal error code return (0); } diff --git a/src/builtin/unset.c b/src/builtin/unset.c index ffcf60f..146b755 100644 --- a/src/builtin/unset.c +++ b/src/builtin/unset.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:51 by charles #+# #+# */ -/* Updated: 2020/04/01 23:05:33 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:17:03 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,10 +25,13 @@ int builtin_unset(char **argv, t_env env) return (1); i = 0; while (i < env->size) + { if (ft_strncmp(env->data[i], argv[1], ft_strlen(argv[1])) == 0) { ft_vecremove(env, i, free); return (0); } + i++; + } return (1); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:09:33 by charles ### ########.fr */ +/* Updated: 2020/04/02 10:33:12 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,9 +32,9 @@ t_env env_from_array(char **envp) while (envp[i] != NULL) if (ft_strchr(envp[i++], '=') == NULL) return (NULL); - if ((env = ft_vecnew(i)) == NULL) + if ((env = ft_vecnew(i + 1)) == NULL) return (NULL); - env->size = i; + env->size = i + 1; i = 0; while (envp[i] != NULL) { @@ -45,6 +45,7 @@ t_env env_from_array(char **envp) } i++; } + env->data[i] = NULL; return (env); } diff --git a/src/eval/eval.c b/src/eval/eval.c index 8c1e509..0e57f15 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/04/01 23:15:16 by charles ### ########.fr */ +/* Updated: 2020/04/02 17:08:18 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,76 +17,160 @@ #include "eval.h" -/* -** \brief Evaluate a line -** \param state State of the evaluation -** \param line Line to evaluate -** \return Last Executed command status or -1 on error -*/ +#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 -static int eval_line(t_eval_state *state, t_line *line) +int io_frame_init(t_io_frame *frame) { - int status; + 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(state, line->left)); - if ((status = eval(state, line->left)) == -1) + 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); - return (eval(state, line->right)); + + 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)); } -/* -** \brief Evaluate a command -** \param state Evaluation state -** \param cmd Command to evaluate -** \return Executable status or -1 on error -*/ +int execve_wrapper(void *params[PARAM_SIZE]) +{ + return (execve( + params[PARAM_EXEC_PATH], + params[PARAM_ARGV], + params[PARAM_ENVP] + )); +} -static int eval_cmd(t_eval_state *state, t_cmd *cmd) +int exec_wrap( + t_io_frame *frame, + void *passed[PARAM_SIZE], + int (*wrapped)(void *params[PARAM_SIZE]) +) { - int child_pid; - char *exec_path; - bool is_builtin; + int status; + pid_t child_pid; - is_builtin = builtin_check_exec_name(cmd->argv[0]); // no fork if builtin - if (!is_builtin) - { - if ((exec_path = exec_search_path(state->path, - env_search(state->env, "PATH"), cmd->argv[0])) == NULL) - return (-1); - } - pipe_setup_parent(cmd, state->pipe_in, state->pipe_out); if ((child_pid = fork()) == -1) return (-1); if (child_pid == 0) { - pipe_setup_child(state->pipe_in, state->pipe_out); - if (is_builtin) - exit(builtin_dispatch_run(cmd->argv, state->env)); - else if (execve(exec_path, cmd->argv, NULL) == -1) + if (dup2(STDIN_FILENO, frame->pipe_in[PIPE_READ]) == -1 || + dup2(STDOUT_FILENO, frame->pipe_out[PIPE_WRITE]) == -1) exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + if ((status = wrapped(passed)) == -1) + exit(EXIT_FAILURE); + exit(status); } wait(&child_pid); 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) +{ + void *params[PARAM_SIZE]; + + params[PARAM_STATE] = state; + params[PARAM_LINE] = line; + return (exec_wrap(frame, params, &eval_root)); +} + +int run_builtin(t_eval_state *state, char **argv) +{ + return (builtin_dispatch_run(argv, state->env)); +} + +/* +** \brief Evaluate a command +** \param state Evaluation state +** \param cmd Command to evaluate +** \return Executable status or -1 on error +*/ + +static int eval_cmd(t_io_frame *frame, t_eval_state *state, t_cmd *cmd) +{ + void *params[PARAM_SIZE]; + + if (builtin_check_exec_name(cmd->argv[0])) + return (run_builtin(state, cmd->argv)); + params[PARAM_EXEC_PATH] = exec_search_path( + state->path, env_search(state->env, "PATH"), cmd->argv[0]); + if (params[PARAM_EXEC_PATH] == NULL) + 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)); +} + +/* ** \brief Evaluate an AST ** \param state State of the evaluation ** \param ast Abstract syntax tree to evaluate ** \return Executable status or -1 on error */ -int eval(t_eval_state *state, t_ast *ast) +int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast) { + void *params[PARAM_SIZE]; + errno = 0; + if (ast->tag == TAG_ROOT) + { + params[PARAM_STATE] = state; + params[PARAM_LINE] = &ast->data.line; + return (eval_root(params)); + } if (ast->tag == TAG_LINE) - return (eval_line(state, &ast->data.line)); + return (eval_line(frame, state, &ast->data.line)); if (ast->tag == TAG_CMD) - return (eval_cmd(state, &ast->data.cmd)); + return (eval_cmd(frame, state, &ast->data.cmd)); return (-1); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:12:51 by charles ### ########.fr */ +/* Updated: 2020/04/03 08:56:46 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -70,9 +70,14 @@ int main(int argc, char **argv, char **envp) state.pipe_out[1] = -1; state.path = path; state.env = env; - printf("ret: %d %s\n", eval(&state, ast), strerror(errno)); + t_io_frame frame; + io_frame_init(&frame); + printf("ret: %d %s\n", eval(&frame,&state, ast), strerror(errno)); - ast_destroy(ast); + /* char buf[2048]; */ + /* printf("%s\n", getcwd(buf, 2048)); */ + /* builtin_env(NULL, state.env); */ + /* ast_destroy(ast); */ /* while ((ret = ft_next_line(STDIN_FILENO, &line)) == 1) */ /* { */ /* if (eval(parse(line)) == -1) */ @@ -80,7 +85,7 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* } */ /* free(line); */ - ft_htdestroy(path, ht_del_str_entry); + ft_htdestroy(path, free); ft_vecdestroy(env, free); return (0); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/27 15:51:01 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:55:28 by charles ### ########.fr */ +/* Updated: 2020/04/03 07:17:04 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,16 +35,19 @@ static t_path st_path_dir_update(t_path path, char *dirname) { DIR *dir; struct dirent *entry; - char *tmp; + char *filepath; if ((dir = opendir(dirname)) == NULL) return (NULL); while ((entry = readdir(dir)) != NULL) { - if ((tmp = ft_strjoin3(dirname, "/", entry->d_name)) == NULL) - return (NULL); - if (ft_htset(path, entry->d_name, tmp, ht_del_str_entry) == NULL) + if ((filepath = ft_strjoin3(dirname, "/", entry->d_name)) == NULL || + ft_htset(path, entry->d_name, filepath, free) == NULL) + { + free(filepath); + closedir(dir); return (NULL); + } } if (closedir(dir) == -1) return (NULL); |
