summaryrefslogtreecommitdiff
path: root/redes
diff options
context:
space:
mode:
Diffstat (limited to 'redes')
-rw-r--r--redes/exec.c25
-rw-r--r--redes/main.c23
-rw-r--r--redes/preproc.c84
-rw-r--r--redes/stages.h7
-rw-r--r--redes/syntax.h6
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;