diff options
Diffstat (limited to 'redes')
| -rw-r--r-- | redes/exec.c | 25 | ||||
| -rw-r--r-- | redes/main.c | 23 | ||||
| -rw-r--r-- | redes/preproc.c | 84 | ||||
| -rw-r--r-- | redes/stages.h | 7 | ||||
| -rw-r--r-- | redes/syntax.h | 6 |
5 files changed, 131 insertions, 14 deletions
diff --git a/redes/exec.c b/redes/exec.c index f7928af..437dfbe 100644 --- a/redes/exec.c +++ b/redes/exec.c @@ -1,4 +1,6 @@ #include <unistd.h> +#include <fcntl.h> + #include "syntax.h" @@ -56,12 +58,12 @@ ExecutableCommand process_pl_command(PlCommand pl_cmd) { FdRedirectVec fd_redirs = make_FdRedirectVec(256); IntVec open_fds = make_IntVec(256); - for (int j = 0; j < pl_cmd.redirects.count, j++) { + for (int j = 0; j < pl_cmd.redirects.count; j++) { Redirect redir = *get_from_RedirectVec(&pl_cmd.redirects, j); FdRedirect fd_redir; int fd; switch (redir.kind) { - case REDIR_FILE_IN: + case REDIR_READ: fd = open(redir.as.filename, O_RDONLY, 0644); push_to_IntVec(&open_fds, fd); fd_redir = (FdRedirect){.to = fd, .redirected = STDIN_FILENO}; @@ -80,7 +82,7 @@ ExecutableCommand process_pl_command(PlCommand pl_cmd) { exit(67); } push_to_FdRedirectVec(&fd_redirs, fd_redir); - } +} char** args = malloc(sizeof(char*) * (arg_vec.count + 1)); for (int i = 0; i < arg_vec.count; i++) { @@ -92,14 +94,14 @@ ExecutableCommand process_pl_command(PlCommand pl_cmd) { } -void execute_command_pipeline(PlCommand* pipeline) { +void execute_command_pipeline(Pipeline pipeline) { int trunk_fd = STDIN_FILENO; int pgid = -1; size_t i = 0; - Connector last_conn; - do { - PlCommand cmd = pipeline[i]; + + for (int i = 0; i < pipeline.count; i++) { + PlCommand cmd = *get_from_Pipeline(&pipeline, i); ExecutableCommand exec_cmd = process_pl_command(cmd); exec_cmd.stdin_fd = trunk_fd; exec_cmd.stdout_fd = STDOUT_FILENO; @@ -115,13 +117,16 @@ void execute_command_pipeline(PlCommand* pipeline) { execute_cmd(exec_cmd, &pgid); for (int j = 0; j < exec_cmd.open_fds.count; j++) { - int fd = *get_from_IntVec(exec_cmd.open_fds.count, j); + int fd = *get_from_IntVec(&exec_cmd.open_fds, j); close(fd); } - - } while (last_conn != CONN_EOL); + } tcsetpgrp(STDIN_FILENO, pgid); while (waitpid(-pgid, NULL, 0) > 0); tcsetpgrp(STDIN_FILENO, getpgrp()); } + +void execute_pipeline_tree(PipelineTree pltree) { + execute_command_pipeline(*pltree.root); +} diff --git a/redes/main.c b/redes/main.c new file mode 100644 index 0000000..dc451f9 --- /dev/null +++ b/redes/main.c @@ -0,0 +1,23 @@ +#include <stdlib.h> +#include <stdio.h> +#include <readline/readline.h> +#include <readline/history.h> +#include <string.h> + +#include "syntax.h" +#include "stages.h" + + +int main() { + char* line; + while (1) { + line = readline("$ "); + if (line[0] == '\0') continue; + if (strcmp(line, "exit") == 0) exit(0); + add_history(line); + Ast ast = lex(line); + PipelineTree pltree = process_ast(ast); + execute_pipeline_tree(pltree); + } + free(line); +} diff --git a/redes/preproc.c b/redes/preproc.c index f29b058..f9c6e9d 100644 --- a/redes/preproc.c +++ b/redes/preproc.c @@ -1,11 +1,87 @@ +#include <assert.h> #include "syntax.h" +void split_str_on_space(char* str, StrVec* result) { + String buf = make_String(256); + for (int pos = 0; str[pos] != '\0'; pos++) { + if (str[pos] == ' ') { + push_to_StrVec(result, inner(&buf)); + buf = make_String(256); + } else { + push_to_String(&buf, str[pos]); + } + } +} + +StrVec process_word(Word word) { + StrVec result = make_StrVec(256); + for (int i = 0; i < word.count; i++) { + Chunk chunk = *get_from_Word(&word, i); + switch (chunk.qmode) { + case SINGLE_Q: + push_to_StrVec(&result, chunk.as.lit_str); + break; + case DOUBLE_Q: + // TODO + exit(67); + break; + case UN_Q: + // TODO: this only does literals, implement the rest + split_str_on_space(chunk.as.lit_str, &result); + break; + } + } + return result; +} -Pipeline process_token_sequence(TokenVec* token_pool, TokenPtrVec ptr_seq) { - +Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) { + Pipeline pl = make_Pipeline(256); + size_t tok_pos = 0; + while (tok_pos < tokens.count) { + PlCommand pl_cmd = { + .args = make_ArgVec(256), + .redirects = make_RedirectVec(256), + }; + Token curr_tok; + for (; + ( + curr_tok = *get_from_TokenVec(&tokens, tok_pos), + !(curr_tok.kind == TOK_SPEC && (curr_tok.as.spec == SPEC_PIPE && curr_tok.as.spec == SPEC_EOL)) + ); + tok_pos++ + ) { + switch (curr_tok.kind) { + case TOK_WORD: + StrVec exp_word = process_word(curr_tok.as.word); + for (int j = 0; j < exp_word.count; j++) { + char* arg_str = *get_from_StrVec(&exp_word, j); + push_to_ArgVec(&pl_cmd.args, (Arg){.kind = ARG_LIT, .as.lit_str = arg_str}); + } + break; + default: + exit(67); // TODO: the other kinds + } + } + Token delim_tok = *get_from_TokenVec(&tokens, tok_pos); + assert(delim_tok.kind == TOK_SPEC); + switch (delim_tok.as.spec) { + case SPEC_PIPE: + pl_cmd.conn = CONN_PIPE; + break; + case SPEC_EOL: + pl_cmd.conn = CONN_EOL; + break; + default: + exit(67); + } + } + return push_to_PipelineVec(pl_pool, pl); } -Pipeline process_into_pipeline(Ast ast) { - exit(1); +PipelineTree process_ast(Ast ast) { + PipelineVec pls = make_PipelineVec(256); + TokenVec root_toks = *ast.root; + Pipeline* root_pl = process_token_sequence(root_toks, &pls); + return (PipelineTree){.pl_pool = pls, root_pl}; } diff --git a/redes/stages.h b/redes/stages.h new file mode 100644 index 0000000..4faaf14 --- /dev/null +++ b/redes/stages.h @@ -0,0 +1,7 @@ +#pragma once + +#include "syntax.h" + +Ast lex(char* input); +PipelineTree process_ast(Ast ast); +void execute_pipeline_tree(PipelineTree pltree); diff --git a/redes/syntax.h b/redes/syntax.h index 70cfe22..b78d4fa 100644 --- a/redes/syntax.h +++ b/redes/syntax.h @@ -154,6 +154,12 @@ struct PlCommand { }; DECLARE_VEC(PlCommand, Pipeline) +DECLARE_VEC(Pipeline, PipelineVec) + +typedef struct { + PipelineVec pl_pool; + Pipeline* root; +} PipelineTree; |
