#include "parser.h" #include "../lib/malloc/malloc.h" #include "../lib/cstr/cstr.h" #include "../lib/sys/write.h" char **__new_argv(char *exp); void __free_argv(char **argv); 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, ' '); 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 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, ' '); char **argv = malloc(sizeof(char*) * n + 1); u64 i = 0; char *current = exp; char *next; for (; n > 0; --n) { next = (char*)next_split(current); strip_cstr(current, ' '); if (cstr_length(current)) argv[i++] = current; current = next; } argv[i] = 0; return argv; } void __free_argv(char **argv) { free(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() { 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 }; int pid[2]; int pipefd[2]; 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