aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
blob: 73a20279a6a2c0ba555219194f182e4e76684436 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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;
}