diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-06-14 16:07:19 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-06-14 16:07:19 +0200 |
| commit | 47fff4418d3a83ae214429f395232c3536ff03c4 (patch) | |
| tree | 8dd1021d3ae899b80cf052ae42a40c4bc965c654 /src/eval | |
| parent | 26ddbd7146f65a2cf100713f422a9ab5b1890620 (diff) | |
| download | minishell-47fff4418d3a83ae214429f395232c3536ff03c4.tar.gz minishell-47fff4418d3a83ae214429f395232c3536ff03c4.tar.bz2 minishell-47fff4418d3a83ae214429f395232c3536ff03c4.zip | |
Added eval cmd and error handling draft, Updated preprocessing for list
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/cmd.c | 110 | ||||
| -rw-r--r-- | src/eval/error.c | 56 | ||||
| -rw-r--r-- | src/eval/eval.c | 93 |
3 files changed, 173 insertions, 86 deletions
diff --git a/src/eval/cmd.c b/src/eval/cmd.c new file mode 100644 index 0000000..2896ab6 --- /dev/null +++ b/src/eval/cmd.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/14 10:41:31 by charles #+# #+# */ +/* Updated: 2020/06/14 12:52:59 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +/* +** \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 fork_wrap( + int fd_in, + int fd_out, + void *passed, + int (*wrapped)(void *param)) +{ + int status; + pid_t child_pid; + + if ((child_pid = fork()) == -1) + return (-1); + if (child_pid == 0) + { + if (dup2(STDIN_FILENO, fd_in) == -1 || + dup2(STDOUT_FILENO, fd_out) == -1) + exit(EXIT_FAILURE); + if ((status = wrapped(passed)) == -1) + exit(EXIT_FAILURE); + exit(status); + } + wait(&child_pid); + return (WEXITSTATUS(child_pid)); +} + +/* +** \brief execve syscall wrapper passed it to fork_wrap +** \param param function params +** \return execve return value +*/ + +int forked_cmd(void *void_param) +{ + t_fork_param_cmd *param; + + param = void_param; + + if (param->builtin != NULL) + return (param->builtin(param->argv, param->env)); + else + return (execve(param->exec_path, param->argv, (char**)param->env->data)); +} + + + +int eval_cmd(t_env env, t_path path, t_ast *ast) +{ + t_fork_param_cmd param; + + // 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) + + 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)); */ +} diff --git a/src/eval/error.c b/src/eval/error.c new file mode 100644 index 0000000..016a751 --- /dev/null +++ b/src/eval/error.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/14 11:02:52 by charles #+# #+# */ +/* Updated: 2020/06/14 12:19:14 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +static t_error g_errors[] = +{ + {ERROR_AMBIGUOUS_REDIR, 1, "ambiguous redirect"}, + {ERROR_OPEN, 1, NULL}, + {ERROR_CMD_NOT_FOUND, 127, "command not found"}, + {ERROR_SYNTAX, 2, "syntax error near unexpected token "}, +}; + +t_error *st_error_get(enum e_error id) +{ + size_t i; + t_error *match; + + match = NULL; + i = 0; + while (i < sizeof(g_errors) / sizeof(t_error)) + { + if (g_errors[i].id == id) + match = &g_errors[i]; + i++; + } + return (match); +} + +void error_eval_put(enum e_error id, char *unexpected) +{ + t_error *err; + + err = st_error_get(id); + ft_putstr_fd("minishell: ", STDERR_FILENO); + ft_putstr_fd(unexpected, STDERR_FILENO); + ft_putstr_fd(": ", STDERR_FILENO); + if (err->msg == NULL) + ft_putendl_fd(strerror(errno), STDERR_FILENO); + else + ft_putendl_fd(err->msg, STDERR_FILENO); +} + +int error_status(enum e_error id) +{ + return (st_error_get(id)->status); +} diff --git a/src/eval/eval.c b/src/eval/eval.c index 1e0a8d7..c1b580f 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,96 +6,17 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/06/14 10:34:11 by charles ### ########.fr */ +/* Updated: 2020/06/14 10:42:37 by charles ### ########.fr */ /* */ /* ************************************************************************** */ -/* #<{(| */ -/* ** \file eval.c */ -/* ** \brief Evaluation of an AST */ -/* |)}># */ -/* */ +/* +** \file eval.c +** \brief Evaluation of an AST +*/ + /* #include "eval.h" */ -/* */ -/* #<{(| */ -/* ** \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 fork_wrap( */ -/* int fd_in, */ -/* int fd_out, */ -/* void *passed, */ -/* int (*wrapped)(void *param)) */ -/* { */ -/* int status; */ -/* pid_t child_pid; */ -/* */ -/* if ((child_pid = fork()) == -1) */ -/* return (-1); */ -/* if (child_pid == 0) */ -/* { */ -/* if (dup2(STDIN_FILENO, fd_in) == -1 || */ -/* dup2(STDOUT_FILENO, fd_out) == -1) */ -/* exit(EXIT_FAILURE); */ -/* if ((status = wrapped(passed)) == -1) */ -/* exit(EXIT_FAILURE); */ -/* exit(status); */ -/* } */ -/* wait(&child_pid); */ -/* return (WEXITSTATUS(child_pid)); */ -/* } */ -/* */ -/* int run_builtin(t_eval_state *state, char **argv) */ -/* { */ -/* return (builtin_dispatch_run(argv, state->env)); */ -/* } */ -/* */ -/* #<{(| */ -/* ** \brief execve syscall wrapper passed it to fork_wrap */ -/* ** \param param function params */ -/* ** \return execve return value */ -/* |)}># */ -/* */ -/* int execve_wrapper(void *param) */ -/* { */ -/* return (execve( */ -/* ((t_fork_param_execve*)param)->exec_path, */ -/* ((t_fork_param_execve*)param)->argv, */ -/* ((t_fork_param_execve*)param)->envp */ -/* )); */ -/* } */ -/* */ -/* #<{(| */ -/* ** \brief Evaluate a command */ -/* ** \param state Evaluation state */ -/* ** \param cmd Command to evaluate */ -/* ** \return Executable status or -1 on error */ -/* |)}># */ -/* */ -/* static int eval_cmd(int fd_in, int fd_out, t_eval_state *state, t_cmd *cmd) */ -/* { */ -/* t_fork_param_execve param; */ -/* */ -/* if (builtin_check_exec_name(cmd->argv[0])) */ -/* return (run_builtin(state, cmd->argv)); */ -/* param.exec_path = exec_search_path( */ -/* state->path, env_search(state->env, "PATH"), cmd->argv[0]); */ -/* 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_WRONLY) | O_CREAT)) == -1) */ -/* return (-1); */ -/* 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 */ |
