diff options
| author | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-10-31 23:41:32 -0400 |
|---|---|---|
| committer | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-10-31 23:41:32 -0400 |
| commit | 06a02a3a50baf261a0f1c998bfd02269c3ed45de (patch) | |
| tree | 00aa66e09a31b2563221c385e5ac129a57082729 /src/command.c | |
| download | hush-06a02a3a50baf261a0f1c998bfd02269c3ed45de.tar.gz | |
Initial commit
Diffstat (limited to 'src/command.c')
| -rw-r--r-- | src/command.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/command.c b/src/command.c new file mode 100644 index 0000000..73a2027 --- /dev/null +++ b/src/command.c @@ -0,0 +1,103 @@ +/* + * + */ + +#include "command.h" +#include "config.h" +#include "lexer.h" +#include <stdio.h> +#include <unistd.h> + +command *commands_from_tokens(token *parsed_cmdstr, size_t *cnt) { + + command *cmd_head = calloc(1, sizeof(command)); + command *cmd = cmd_head; + size_t arg_cnt = 1; + + *cnt = 0; + + token *prev_tkn = NULL; + + for (token *tkn = parsed_cmdstr; tkn; prev_tkn = tkn, tkn = tkn->next) { + if (tkn->type == TKN_COMMAND) { + cmd->command = tkn->text; + cmd->args[0] = tkn->text; + arg_cnt = 1; + (*cnt)++; + } else if (tkn->type == TKN_ARG) { + cmd->args[arg_cnt++] = tkn->text; + } else if (tkn->type == TKN_FILENAME) { + if (prev_tkn->type == TKN_IN_REDIR) { + cmd->infile = tkn->text; + } else { + cmd->outfile = tkn->text; + } + } else if (tkn->type == TKN_PIPE) { + cmd->next = calloc(1, sizeof(command)); + cmd->next->read_pipe = cmd->pipe; + cmd = cmd->next; + } + + } + + return cmd_head; +} + +void print_commands(FILE *file, command *cmds) { + for (command *cmd=cmds; cmd; cmd = cmd->next) { + fprintf(file, "Command: %s\n", cmd->command); + fprintf(file, "\t"); + 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", cmd->infile, cmd->outfile); + } +} + +void destroy_commands(command *cmds) { + command **cmd_ptr = &cmds->next; + while (*cmd_ptr) { + free(cmds); + cmds = *cmd_ptr; + cmd_ptr = &cmds->next; + } +} + +pid_t execute_command(command *cmd) { + if (cmd->next) { + pipe(cmd->pipe); + } + + pid_t res = fork(); + if (res == 0) { + if (cmd->infile) { + if (!freopen(cmd->infile, "r", stdin)) { + perror("Could not open input file"); + exit(EXIT_FAILURE); + } + } else if (cmd->read_pipe) { + dup2(*(cmd->read_pipe), STDIN_FILENO); + close(*(cmd->read_pipe)); + } + + if (cmd->outfile) { + if (!freopen(cmd->outfile, "w", stdout)) { + perror("Could not open output file"); + exit(EXIT_FAILURE); + } + } else if (cmd->next) { + dup2(cmd->pipe[1], STDOUT_FILENO); + close(cmd->pipe[1]); + } + + + int res = execvp(cmd->command, cmd->args); + perror("Could not run command"); + exit(EXIT_FAILURE); + } else if (res < 0) { + perror("Could not run command"); + } + + cmd->pid = res; + return res; +} |