aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c13
-rw-r--r--src/eval/cmd.c131
-rw-r--r--src/lexer/token.c9
-rw-r--r--src/main.c77
-rw-r--r--src/preprocess.c22
5 files changed, 172 insertions, 80 deletions
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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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, &param, &execve_wrapper)); */
+ param.argv = argv;
+ param.env = env;
+ return (fork_wrap(fd_in, fd_out, &param, &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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
+}