diff options
| author | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-11-01 13:35:36 -0400 |
|---|---|---|
| committer | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-11-01 13:35:36 -0400 |
| commit | 406889ed5c780f0e28703b143c72bbf035280b25 (patch) | |
| tree | 9158054087bda207eed65e13e3e706ceb8467388 | |
| parent | 1c2f33050478e5c859fa7be390681b39ee7311b2 (diff) | |
| download | hush-406889ed5c780f0e28703b143c72bbf035280b25.tar.gz | |
Got pipelining fully working
| -rw-r--r-- | include/command.h | 2 | ||||
| -rw-r--r-- | src/command.c | 66 | ||||
| -rw-r--r-- | src/hush.c | 7 | ||||
| -rw-r--r-- | src/lexer.c | 14 |
4 files changed, 50 insertions, 39 deletions
diff --git a/include/command.h b/include/command.h index 3df724b..f44c103 100644 --- a/include/command.h +++ b/include/command.h @@ -15,10 +15,10 @@ typedef struct command { char *infile; char *outfile; struct command *next; + struct command *prev; pid_t pid; int pipe[2]; - int *read_pipe; char *args[MAX_ARGUMENT_CNT + 2]; } command; diff --git a/src/command.c b/src/command.c index ea198ec..20b00b1 100644 --- a/src/command.c +++ b/src/command.c @@ -18,12 +18,12 @@ command *create_command() { memset(cmd->args, 0, sizeof(char*)); cmd->pipe[0] = -1; cmd->pipe[1] = -1; - cmd->read_pipe = NULL; cmd->infile = NULL; cmd->outfile = NULL; - cmd->next = NULL; - cmd->pid = 0; + cmd->pid = -1; + cmd->next = NULL; + cmd->prev= NULL; return cmd; } @@ -53,7 +53,7 @@ command *commands_from_tokens(token *parsed_cmdstr, size_t *cnt) { } } else if (tkn->type == TKN_PIPE) { cmd->next = create_command(); - cmd->next->read_pipe = cmd->pipe; + cmd->next->prev = cmd; cmd = cmd->next; } @@ -69,14 +69,16 @@ void print_commands(FILE *file, command *cmds) { for (size_t i=0; i<MAX_ARGUMENT_CNT; i++) { fprintf(file, "%s ", cmd->args[i]); } - fprintf(file, "\n\tInfile: %s\n\tOutfile: %s\n\tInput Pipe: %p\n\tPid:%d\n", cmd->infile, cmd->outfile, cmd->read_pipe, cmd->pid); - if (cmd->read_pipe) { - fprintf(file, "\tInput Pipe: %d\n", *cmd->read_pipe); - } + fprintf(file, "\n\tInfile: %s\n\tOutfile: %s\\n\tPid:%d\n", cmd->infile, cmd->outfile, cmd->pid); + fprintf(file, "\tRead Pipe: %d\tWrite Pipe: %d\n", cmd->pipe[0], cmd->pipe[1]); } } void destroy_commands(command *cmds) { + if (!cmds) { + return; + } + command **cmd_ptr = &cmds->next; while (*cmd_ptr) { free(cmds); @@ -86,47 +88,36 @@ void destroy_commands(command *cmds) { } pid_t execute_command(command *cmd) { - if (cmd->next) { - pipe(cmd->pipe); + if (cmd->next && pipe(cmd->pipe) == -1) { + perror("Failed to create pipes"); + return -1; } pid_t res = fork(); if (res == 0) { - int fdi = -1, fdo = -1; - - if (cmd->infile) { - if (!freopen(cmd->infile, "r", stdin)) { - perror("Could not open input file"); + if (cmd->infile && !freopen(cmd->infile, "r", stdin)) { + perror("Could not open input file"); + exit(EXIT_FAILURE); + } else if (cmd->prev) { + close(cmd->prev->pipe[1]); + if (dup2(cmd->prev->pipe[0], STDIN_FILENO) == -1) { + perror("Could not assign pipe to stdin"); exit(EXIT_FAILURE); } - } else if (cmd->read_pipe && *cmd->read_pipe >= 0) { - fdi = dup2(*(cmd->read_pipe), STDIN_FILENO); - close(*(cmd->read_pipe)); + close(cmd->prev->pipe[0]); } - if (cmd->outfile) { - if (!freopen(cmd->outfile, "w", stdout)) { + if (cmd->outfile && !freopen(cmd->outfile, "w", stdout)) { perror("Could not open output file"); exit(EXIT_FAILURE); - } } else if (cmd->next) { - fdo = dup2(cmd->pipe[1], STDOUT_FILENO); - } - - fprintf(stderr, "In command:\n"); - fprintf(stderr, "STDIN: %d\tSTDOUT: %d\n", fdi, fdo); - - - if (cmd->pipe[0] >= 0) { close(cmd->pipe[0]); - cmd->pipe[0] = -1; - } - - if (cmd->pipe[1] >= 0) { + if (dup2(cmd->pipe[1], STDOUT_FILENO) == -1) { + perror("Could not assign pipe to stdout"); + exit(EXIT_FAILURE); + } close(cmd->pipe[1]); - cmd->pipe[1] = -1; } - execvp(cmd->command, cmd->args); perror("Could not run command"); @@ -136,6 +127,11 @@ pid_t execute_command(command *cmd) { return -1; } + if (cmd->prev) { + close(cmd->prev->pipe[0]); + close(cmd->prev->pipe[1]); + } + cmd->pid = res; return res; } @@ -87,7 +87,7 @@ int main(int argc, char **argv) { } } - print_commands(stdout, cmds); + // print_commands(stdout, cmds); for (command *cmd = cmds; cmd; cmd = cmd->next) { if (cmd->pid > 0) { @@ -97,12 +97,13 @@ int main(int argc, char **argv) { } } - free_tokens: - destroy_tokens(parsed_cmd); free_commands: destroy_commands(cmds); + free_tokens: + destroy_tokens(parsed_cmd); + draw_prompt: fprintf(stdout, "$ "); } diff --git a/src/lexer.c b/src/lexer.c index a6af008..38ae558 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -153,6 +153,7 @@ token *validate_command(token *cmd) { bool infile_defined = false; bool outfile_defined = false; bool looking_for_file = false; + bool reads_from_pipe = false; for (token *tkn = cmd; tkn; tkn = tkn->next) { if (!prev) { @@ -183,6 +184,15 @@ token *validate_command(token *cmd) { } arg_cnt = 0; + reads_from_pipe = true; + + if (infile_defined) { + return tkn; + } + + infile_defined = false; + outfile_defined = false; + } else if (tkn->type == TKN_IN_REDIR || tkn->type == TKN_OUT_REDIR) { if (prev->type == TKN_PIPE || prev->type == TKN_IN_REDIR || prev->type == TKN_OUT_REDIR) { @@ -196,6 +206,10 @@ token *validate_command(token *cmd) { if (prev->type != TKN_VARKEY) { return tkn; } + } else if (tkn->type == TKN_PIPE) { + if (outfile_defined) { + return tkn; + } } if (looking_for_file && |