diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-03-02 14:20:38 +1300 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-03-02 14:20:38 +1300 |
commit | d0b392c0a4c4ef72a972a32cee2a4e4f155faf5f (patch) | |
tree | 04ca5d9349dc0d463d0edc89a5219c3213c035d1 /cmd.c | |
download | spsh-d0b392c0a4c4ef72a972a32cee2a4e4f155faf5f.tar.gz spsh-d0b392c0a4c4ef72a972a32cee2a4e4f155faf5f.zip |
First commit of sps(1)
Diffstat (limited to 'cmd.c')
-rw-r--r-- | cmd.c | 57 |
1 files changed, 57 insertions, 0 deletions
@@ -0,0 +1,57 @@ +#include "sps.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]; + char *cmd_envp[MAX_ENVS]; + + /* 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; + + /* Environment is just empty for now, I'll figure this out later */ + cmd_envp[0] = NULL; + + + /* 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, cmd_envp); + } + 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; +} + |