From 11a719bab26b3ccccbd219decab2d0cf77021004 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 12:39:56 +0200 Subject: Refactoring redirection out of eval/cmd.c, Added tag check shortcut --- src/eval/cmd.c | 91 ++++---------------------------------------------------- src/eval/redir.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 86 deletions(-) create mode 100644 src/eval/redir.c (limited to 'src/eval') diff --git a/src/eval/cmd.c b/src/eval/cmd.c index 958c7ae..9468cb2 100644 --- a/src/eval/cmd.c +++ b/src/eval/cmd.c @@ -6,14 +6,12 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/14 10:41:31 by charles #+# #+# */ -/* Updated: 2020/06/15 10:58:59 by charles ### ########.fr */ +/* Updated: 2020/06/15 11:09:38 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 @@ -35,8 +33,8 @@ int fork_wrap( return (-1); if (child_pid == 0) { - if (dup2(fd_in, STDIN_FILENO) == -1 || - dup2(fd_out, STDOUT_FILENO) == -1) + if ((fd_in != MS_NO_FD && dup2(fd_in, STDIN_FILENO) == -1) || + (fd_out != MS_NO_FD && dup2(fd_out, STDOUT_FILENO) == -1)) exit(EXIT_FAILURE); if ((status = wrapped(passed)) == -1) exit(EXIT_FAILURE); @@ -58,85 +56,6 @@ int forked_cmd(void *void_param) return (execve(param->exec_path, param->argv, (char**)param->env->data)); } -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; - } - if ((filename = preprocess_filename(&redirs->next, env)) == NULL) - { - ft_lstdestroy(&redirs, (void (*)(void*))token_destroy); - ft_lstdestroy(&after, (void (*)(void*))token_destroy); - return (false); - } - if (redir_has_tag(redirs, TAG_REDIR_IN)) - { - if (*fd_in != STDIN_FILENO) - close(*fd_in); - if ((*fd_in = open(filename, O_RDONLY)) == -1) - { - error_eval_put(ERROR_OPEN, filename); - ft_lstdestroy(&redirs, (void (*)(void*))token_destroy); - ft_lstdestroy(&after, (void (*)(void*))token_destroy); - free(filename); - return (false); - } - } - else if (redir_has_tag(redirs, TAG_REDIR_OUT)) - { - if (*fd_out != STDOUT_FILENO) - close(*fd_out); - if ((*fd_out = open(filename, - O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) - { - error_eval_put(ERROR_OPEN, filename); - ft_lstdestroy(&redirs, (void (*)(void*))token_destroy); - ft_lstdestroy(&after, (void (*)(void*))token_destroy); - free(filename); - return (false); - } - } - else if (redir_has_tag(redirs, TAG_REDIR_APPEND)) - { - if (*fd_out != STDOUT_FILENO) - close(*fd_out); - if ((*fd_out = open(filename, - O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) - { - error_eval_put(ERROR_OPEN, filename); - ft_lstdestroy(&redirs, (void (*)(void*))token_destroy); - ft_lstdestroy(&after, (void (*)(void*))token_destroy); - free(filename); - return (false); - } - } - ft_lstdestroy(&redirs, (void (*)(void*))token_destroy); - free(filename); - 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; @@ -144,8 +63,8 @@ int eval_cmd(t_env env, t_path path, t_ast *ast) int fd_out; char **argv; - fd_in = STDIN_FILENO; - fd_out = STDOUT_FILENO; + fd_in = MS_NO_FD; + fd_out = MS_NO_FD; if (!redir_extract(ast->redirs, env, &fd_in, &fd_out)) { ast->redirs = NULL; diff --git a/src/eval/redir.c b/src/eval/redir.c new file mode 100644 index 0000000..c6f98d4 --- /dev/null +++ b/src/eval/redir.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/15 11:05:34 by charles #+# #+# */ +/* Updated: 2020/06/15 11:44:38 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +static enum e_token_tag st_lst_tag(t_ftlst *lst) +{ + return (((t_token*)lst->data)->tag); +} + +static bool st_open_replace(int *fd, char *filename, int oflag) +{ + if (*fd != MS_NO_FD) + close(*fd); + if (oflag & O_CREAT) + *fd = open(filename, oflag, 0644); + else + *fd = open(filename, oflag); + if (*fd == -1) + { + error_eval_put(ERROR_OPEN, filename); + free(filename); + return (false); + } + return (true); +} + +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 (!(st_lst_tag(redirs) & TAG_IS_REDIR) || redirs->next == NULL + || !(st_lst_tag(redirs->next) & TAG_IS_STR)) + return (false); + curr = redirs->next; + while (curr != NULL && st_lst_tag(curr) & TAG_IS_STR) + { + if (curr->next == NULL || st_lst_tag(curr->next) & TAG_IS_REDIR) + { + after = curr->next; + curr->next = NULL; + } + curr = curr->next; + } + if ((filename = preprocess_filename(&redirs->next, env)) == NULL) + { + token_destroy_lst2(redirs, after); + return (false); + } + if ((st_lst_tag(redirs) == TAG_REDIR_IN + && !st_open_replace(fd_in, filename, O_RDONLY)) + || (st_lst_tag(redirs) == TAG_REDIR_OUT + && !st_open_replace(fd_out, filename, O_WRONLY | O_CREAT | O_TRUNC)) + || (st_lst_tag(redirs) == TAG_REDIR_APPEND + && !st_open_replace(fd_out, filename, O_WRONLY | O_CREAT | O_APPEND))) + { + token_destroy_lst2(redirs, after); + return (false); + } + token_destroy_lst(redirs); + free(filename); + return (redir_extract(after, env, fd_in, fd_out)); +} -- cgit