aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
diff options
context:
space:
mode:
authorDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2025-10-31 23:41:32 -0400
committerDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2025-10-31 23:41:32 -0400
commit06a02a3a50baf261a0f1c998bfd02269c3ed45de (patch)
tree00aa66e09a31b2563221c385e5ac129a57082729 /src/command.c
downloadhush-06a02a3a50baf261a0f1c998bfd02269c3ed45de.tar.gz
Initial commit
Diffstat (limited to 'src/command.c')
-rw-r--r--src/command.c103
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;
+}