diff options
Diffstat (limited to 'smash/parser.c')
| -rw-r--r-- | smash/parser.c | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/smash/parser.c b/smash/parser.c index 33fb410..22b9ccf 100644 --- a/smash/parser.c +++ b/smash/parser.c @@ -14,21 +14,44 @@ expression_list_t *new_expression_from_line(char *line) u64 n = cstr_split(line, '|'); char *current = line; char *next = 0; - + expression_list_t *head = 0; + expression_list_t *expression = 0; for (; n > 0; --n) { next = (char*)next_split(current); strip_cstr(current, ' '); - write(0, current, cstr_length(current)); - write(0, "\\n\n", 3); + if (!expression) { + expression = malloc(sizeof(expression_list_t)); + head = expression; + } else { + expression->next = malloc(sizeof(expression_list_t)); + expression = expression->next; + } + + expression->call = current; + expression->next = 0; current = next; } - return 0; + + return head; } + +void free_expression(expression_list_t *expression) +{ + expression_list_t *next; + + while (expression) { + next = expression->next; + free(expression); + expression = next; + } +} + + char **__new_argv(char *exp) { u64 n = cstr_split(exp, ' '); @@ -61,16 +84,54 @@ void __free_argv(char **argv) #ifdef PARSER_UNIT_TEST #include "../lib/sys/execve.h" +#include "../lib/sys/fork.h" +#include "../lib/sys/wait4.h" +#include "../lib/sys/pipe.h" +#include "../lib/sys/dup2.h" +#include "../lib/sys/close.h" +#include "../lib/sys/io.h" +#include "../lib/sys/exit.h" int main() { - const char exp[] = "/bin/ls -a -l -h"; - char **argv = __new_argv(exp); - char **p = argv; - char *const envp[] = { 0 }; + char in[] = "/bin/ls -a | /bin/wc -l"; + expression_list_t *exps = new_expression_from_line(in); + expression_list_t *exp = exps; + char **envp = { 0 }; - execve(argv[0], argv, envp); + int pid[2]; + int pipefd[2]; - free(argv); + char **argv1 = __new_argv(exp->call); + char **argv2 = __new_argv(exp->next->call); + + pipe(pipefd); + pid[0] = fork(); + + if (pid[0] == 0) { + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FD); + close(pipefd[1]); + + execve(argv1[0], argv1, envp); + } else { + pid[1] = fork(); + + + close(pipefd[1]); + + if (pid[1] == 0) { + dup2(pipefd[0], STDIN_FD); + close(pipefd[0]); + + execve(argv2[0], argv2, envp); + } else { + close(pipefd[0]); + wait4(pid[0], 0, 0); + wait4(pid[1], 0, 0); + } + } + + return 0; } #endif |