From 91d91b0f54ec9795beaf673f20ff87b894a558c4 Mon Sep 17 00:00:00 2001 From: Charles Date: Sun, 14 Jun 2020 21:26:36 +0200 Subject: WIP: Added eval cmd with redirection and builtins --- src/ast.c | 13 ++---- src/eval/cmd.c | 131 +++++++++++++++++++++++++++++++++++++----------------- src/lexer/token.c | 9 ++-- src/main.c | 77 +++++++++++++++++++++----------- src/preprocess.c | 22 ++++++++- 5 files changed, 172 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/ast.c b/src/ast.c index 98ca4ac..1f96b8e 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/06/14 10:29:21 by charles ### ########.fr */ +/* Updated: 2020/06/14 20:22:26 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,9 +30,7 @@ t_ast *ast_new(enum e_ast_tag tag) if ((ast = (t_ast*)malloc(sizeof(t_ast))) == NULL) return (NULL); ast->tag = tag; - ast->in = NULL; - ast->out = NULL; - ast->is_append = false; + ast->redirs = NULL; ast->line.left = NULL; ast->line.right = NULL; ast->cmd_argv = NULL; @@ -48,12 +46,9 @@ void ast_destroy(t_ast *ast) { if (ast == NULL) return ; + ft_lstdestroy(&ast->cmd_argv, (void (*)(void*))token_destroy); if (ast->tag == AST_CMD) - { - ft_lstdestroy(&ast->cmd_argv, (void (*)(void*))token_destroy); - ft_lstdestroy(&ast->in, (void (*)(void*))token_destroy); - ft_lstdestroy(&ast->out, (void (*)(void*))token_destroy); - } + ft_lstdestroy(&ast->redirs, (void (*)(void*))token_destroy); else if (ast->tag == AST_LINE) { ast_destroy(ast->line.left); diff --git a/src/eval/cmd.c b/src/eval/cmd.c index 2896ab6..027c75b 100644 --- a/src/eval/cmd.c +++ b/src/eval/cmd.c @@ -6,12 +6,14 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/14 10:41:31 by charles #+# #+# */ -/* Updated: 2020/06/14 12:52:59 by charles ### ########.fr */ +/* Updated: 2020/06/14 21:23:20 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "eval.h" +#define MS_NO_FD -2 + /* ** \brief Wrap a function in a fork ** \param fd_in fork input file descriptor @@ -33,8 +35,8 @@ int fork_wrap( return (-1); if (child_pid == 0) { - if (dup2(STDIN_FILENO, fd_in) == -1 || - dup2(STDOUT_FILENO, fd_out) == -1) + if (dup2(fd_in, STDIN_FILENO) == -1 || + dup2(fd_out, STDOUT_FILENO) == -1) exit(EXIT_FAILURE); if ((status = wrapped(passed)) == -1) exit(EXIT_FAILURE); @@ -62,49 +64,98 @@ int forked_cmd(void *void_param) return (execve(param->exec_path, param->argv, (char**)param->env->data)); } +int open_redirection(t_ftlst *filename_tokens, t_env env, int oflag) +{ + // check in and out (single string) + // argv[0]: [string]: ambiguous redirect code 1 + + // check in and out (exist) + // argv[0]: [string]: No such file or directory (probably from errno) + + char *filename; + int fd; + + if (filename_tokens == NULL) + return (MS_NO_FD); + if ((filename = preprocess_filename(filename_tokens, env)) == NULL) + return (-1); + if ((fd = open(filename, oflag)) == -1) + return (-1); //file error; + return (fd); +} + +bool redir_has_tag(t_ftlst *redir, enum e_token_tag tags) +{ + return (((t_token*)redir->data)->tag & tags); +} +bool redir_extract(t_ftlst *redirs, t_env env, int *fd_in, int *fd_out) +{ + t_ftlst *after; + t_ftlst *curr; + char *filename; + + if (redirs == NULL) + return (true); + if (!redir_has_tag(redirs, TAG_REDIR_IN | TAG_REDIR_OUT | TAG_REDIR_APPEND) + || redirs->next == NULL + || !redir_has_tag(redirs->next, TAG_STR | TAG_STR_SINGLE | TAG_STR_DOUBLE)) + return (false); + curr = redirs->next; + while (curr != NULL && redir_has_tag(curr, TAG_STR | TAG_STR_SINGLE | TAG_STR_DOUBLE)) + { + if (curr->next == NULL || redir_has_tag(curr->next, TAG_REDIR_IN | TAG_REDIR_OUT | TAG_REDIR_APPEND)) + { + after = curr->next; + curr->next = NULL; + } + curr = curr->next; + } + filename = preprocess_filename(redirs->next, env); + if (redir_has_tag(redirs, TAG_REDIR_IN)) + { + if (*fd_in != STDIN_FILENO) + close(*fd_in); + if ((*fd_in = open(filename, O_RDONLY)) == -1) + return (false); + } + else if (redir_has_tag(redirs, TAG_REDIR_OUT | TAG_REDIR_APPEND)) + { + if (*fd_out != STDOUT_FILENO) + close(*fd_out); + if ((*fd_out = open(filename, + (redir_has_tag(redirs, TAG_REDIR_APPEND) ? O_APPEND : O_WRONLY) + | O_CREAT | O_TRUNC, 0644)) == -1) + return (false); + } + return (redir_extract(after, env, fd_in, fd_out)); +} int eval_cmd(t_env env, t_path path, t_ast *ast) { t_fork_param_cmd param; + int fd_in; + int fd_out; + char **argv; - // check in and out (single string) - // argv[0]: [string]: ambiguous redirect code 1 + fd_in = STDIN_FILENO; + fd_out = STDOUT_FILENO; + if (!redir_extract(ast->redirs, env, &fd_in, &fd_out)) + return (-1); - // check in and out (exist) - // argv[0]: [string]: No such file or directory (probably from errno) + argv = preprocess(ast->cmd_argv, env); + + param.builtin = builtin_search_func(argv[0]); + if (param.builtin == NULL) + { + param.exec_path = exec_search_path(path, env_search(env, "PATH"), argv[0]); + /* // get cmd path */ + /* // argv[0]: [string]: command not found code 127 */ + if (param.exec_path == NULL) + return (-1); //not_found; + } - return (0); - /* if (in != NULL) */ - /* { */ - /* char **redir_in = preprocess(in); */ - /* if (redir_in[1] != NULL) */ - /* ambiguous; */ - /* if ((fd_in = open(cmd->in, O_RDONLY)) == -1) */ - /* file error; */ - /* } */ - /* */ - /* if (out != NULL) */ - /* { */ - /* char **redir_out = preprocess(out); */ - /* if (redir_out[1] != NULL) */ - /* ambiguous; */ - /* if ((fd_out = open(cmd->out, (is_append ? O_APPEND : O_WRONLY) | O_CREAT)) == -1) */ - /* file error; */ - /* } */ - /* */ - /* char **argv = preprocess(cmd_argv); */ - /* */ - /* param.builtin = builtin_search_func(argv[0]); */ - /* if (param.builtin) */ - /* param.exec_path = exec_search_path(path, env_search(env, "PATH"), argv[0]); */ - /* */ - /* // get cmd path */ - /* // argv[0]: [string]: command not found code 127 */ - /* if (param.exec_path == NULL) */ - /* not_found; */ - /* */ - /* param.argv = argv; */ - /* param.env = env; */ - /* return (fork_wrap(fd_in, fd_out, ¶m, &execve_wrapper)); */ + param.argv = argv; + param.env = env; + return (fork_wrap(fd_in, fd_out, ¶m, &forked_cmd)); } diff --git a/src/lexer/token.c b/src/lexer/token.c index 490c7b1..0a13526 100644 --- a/src/lexer/token.c +++ b/src/lexer/token.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/09 13:38:08 by charles #+# #+# */ -/* Updated: 2020/06/09 17:55:23 by charles ### ########.fr */ +/* Updated: 2020/06/14 20:51:25 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,10 +16,11 @@ t_token *token_new(enum e_token_tag tag, char *content) { t_token *token; - if (content == NULL - || (token = (t_token*)malloc(sizeof(t_token))) == NULL) + if ((token = (t_token*)malloc(sizeof(t_token))) == NULL) return (NULL); - if ((token->content = ft_strdup(content)) == NULL) + if (content == NULL) + token->content = NULL; + else if ((token->content = ft_strdup(content)) == NULL) { free(token); return (NULL); diff --git a/src/main.c b/src/main.c index 0f5b92c..e81c634 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/06/14 16:04:41 by charles ### ########.fr */ +/* Updated: 2020/06/14 21:21:01 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,20 +17,21 @@ #include "minishell.h" #include "ast.h" -#include "lexer.h" -#include "parser.h" +/* #include "lexer.h" */ +/* #include "parser.h" */ +#include "eval.h" int main(int argc, char **argv, char **envp) { (void)argc; (void)argv; /* (void)envp; */ - /* t_path path; */ + t_path path; t_env env; /* char *line; */ /* int ret; */ env = env_from_array(envp); - /* path = path_update(NULL, env_search(env, "PATH")); */ + path = path_update(NULL, env_search(env, "PATH")); /* */ /* t_ast *ast; */ /* t_line line; */ @@ -74,34 +75,58 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* } */ /* free(line); */ - /* ft_htdestroy(path, free); */ /* ms_glob("src#<{(|"); */ /* char *j = ms_glob("|)}>#*.c"); */ /* printf("%s\n", j); */ /* free(j); */ - t_ftlst *l = NULL; - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$TERM$LFS$TERM$TERM."))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$$LFS$TERM$TERM."))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "*/*.c"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "src/*.c include/*.h"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$A$B"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\$TERM"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$TER\\M"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\\\"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "''''$TEST\\TEST"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE, ",$TEST,$B,"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE , "$TEST"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); - ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "$TEST"))); - char **as = preprocess(l, env); + + t_ftlst *args = NULL; + ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "echo"))); + ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "bonjour"))); + ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "je"))); + + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "cat"))); */ + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-e"))); */ + + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "ls"))); */ + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-a"))); */ + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-l"))); */ + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "$$LFS$TERM$TERM."))); */ + /* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "|)}>#*.c"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "src#<{(|.c include#<{(|.h"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$A$B"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\$TERM"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$TER\\M"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\\\"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "''''$TEST\\TEST"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE, ",$TEST,$B,"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE , "$TEST"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); */ + /* ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "$TEST"))); */ + + t_ftlst *redirs = NULL; + /* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_REDIR_IN, NULL))); */ + /* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_STR, "bonjour"))); */ + ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_REDIR_OUT, NULL))); + ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_STR, "yo"))); + + t_ast *ast = ast_new(AST_CMD); + ast->cmd_argv = args; + ast->redirs = redirs; + + printf("eval %d\n", eval_cmd(env, path, ast)); + + + /* char **as = preprocess(l, env); */ /* printf("%p\n", as); */ /* printf("%p\n", *as); */ - char **tmp = as; - while (*as != NULL) - puts(*as++); + /* char **tmp = as; */ + /* while (*as != NULL) */ + /* puts(*as++); */ /* ft_split_destroy(tmp); */ + ft_htdestroy(path, free); ft_vecdestroy(env, free); return (0); } diff --git a/src/preprocess.c b/src/preprocess.c index 22f42ab..278e8ef 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/06/14 16:02:46 by charles ### ########.fr */ +/* Updated: 2020/06/14 21:25:05 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -113,6 +113,7 @@ static void st_iter_func_unwrap_token(void **addr) *(char**)addr = content; } +// need to free argv on error char **preprocess(t_ftlst *tokens, t_env env) { size_t i; @@ -157,3 +158,22 @@ char **preprocess(t_ftlst *tokens, t_env env) ft_vecpush(argv, NULL); return ((char**)ft_vecunwrap(argv)); } + +// need to free tokens +char *preprocess_filename(t_ftlst *tokens, t_env env) +{ + char **strs; + char *ret; + + if ((strs = preprocess(tokens, env)) == NULL + || strs[0] == NULL) + return (NULL); + if (strs[1] != NULL) + { + // ambiguous + return (NULL); + } + ret = strs[0]; + free(strs); + return (ret); +} -- cgit