From 06a02a3a50baf261a0f1c998bfd02269c3ed45de Mon Sep 17 00:00:00 2001 From: "Douglas B. Rumbaugh" Date: Fri, 31 Oct 2025 23:41:32 -0400 Subject: Initial commit --- src/command.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/command.c (limited to 'src/command.c') 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 +#include + +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; iargs[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; +} -- cgit v1.2.3