aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtin/cd.c10
-rw-r--r--src/builtin/echo.c6
-rw-r--r--src/builtin/export.c4
-rw-r--r--src/builtin/unset.c5
-rw-r--r--src/env.c7
-rw-r--r--src/eval/eval.c160
-rw-r--r--src/main.c13
-rw-r--r--src/path.c13
8 files changed, 155 insertions, 63 deletions
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);
}
diff --git a/src/env.c b/src/env.c
index 66b4994..631c2b4 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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);
}
diff --git a/src/main.c b/src/main.c
index c46324f..f898bf8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}
diff --git a/src/path.c b/src/path.c
index f1424cc..1576a66 100644
--- a/src/path.c
+++ b/src/path.c
@@ -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);