aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-04-12 18:36:17 +0200
committerCharles <sircharlesaze@gmail.com>2020-05-04 12:01:03 +0200
commit9fabc25a980550afc6337fd729632462f2680daa (patch)
treef86939c99fe918fa35f4b0d12bc00e03f034ac8d
parent4aeba6d2f03706fa21281709a138a7d3ea9797dc (diff)
downloadminishell-9fabc25a980550afc6337fd729632462f2680daa.tar.gz
minishell-9fabc25a980550afc6337fd729632462f2680daa.tar.bz2
minishell-9fabc25a980550afc6337fd729632462f2680daa.zip
Removing data name in ast union, io_frame, root line ast tag
-rw-r--r--README.md4
-rw-r--r--include/ast.h19
-rw-r--r--include/eval.h23
-rw-r--r--src/ast.c16
-rw-r--r--src/eval/eval.c194
-rw-r--r--src/preprocess.c2
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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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, &param, &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(&param));
}
- 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */