aboutsummaryrefslogtreecommitdiff
path: root/cmd.c
blob: b428d58deee6c88354d018629cf35f23c2ead1ed (plain) (blame)
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
#include "spsh.h"

/* Process a read line into a command and arguments and try to execute it */
void cmd(char *line) {
    char *cmd, *cmd_arg;
    pid_t pid;
    int status, cmd_argc;
    char *cmd_argv[MAX_ARGS];

    /* First argument is always the executable file itself; we make it NULL to
     * start with, and then terminate the array with NULL */
    cmd_argv[0] = cmd_argv[1] = NULL;
    cmd_argc = 1;

    /* Read the command as the first token of the line */
    cmd = strtok(line, ARG_DELIM);

    /* Iterate through the remaining arguments with subsequent calls to strtok() */
    while ((cmd_arg = strtok(NULL, ARG_DELIM)) != NULL) {
        cmd_argc++;
        if (cmd_argc < MAX_ARGS) {
            cmd_argv[cmd_argc - 1] = cmd_arg;
            cmd_argv[cmd_argc] = NULL;
        }
    }

    /* If there were too many arguments, say so */
    if (cmd_argc >= MAX_ARGS) {
        fprintf(stderr, "Too many arguments (%u given, max is %u)\n", cmd_argc, MAX_ARGS);
        return;
    }

    /* If the command looks to be executable ... */
    if (access(cmd, X_OK) != -1) {

        /* ... fork and try to execute it; wait until the fork is done. */
        pid = fork();
        if (pid == 0) {
            cmd_argv[0] = cmd;
            execve(cmd, cmd_argv, environ);
        }
        waitpid(pid, &status, 0);
    }

    /* Otherwise, print an error, because we couldn't find the command */
    else {
        fprintf(stderr, "Command ā€œ%sā€ not found\n", cmd);
        return;
    }

    return;
}