From d963d07d653919ae85ce518f664e3faf0add4a5e Mon Sep 17 00:00:00 2001 From: Trevor Barnes Date: Thu, 23 Feb 2023 22:22:24 -0600 Subject: [PATCH] shell finally working --- 02-TeenyTinyShell/ttsh | Bin 20384 -> 21208 bytes 02-TeenyTinyShell/ttsh.c | 88 ++++++++++++++++++++++++--------------- 02-TeenyTinyShell/ttsh.o | Bin 8704 -> 10640 bytes CS3841.code-workspace | 4 +- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/02-TeenyTinyShell/ttsh b/02-TeenyTinyShell/ttsh index b8bdfd96b4f4e1e5ad8c020b63dfbf14f3ab4a77..cb698c16e210e8e888a469421981aa117c3ceed3 100644 GIT binary patch literal 21208 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 F{U1I4S=9gl diff --git a/02-TeenyTinyShell/ttsh.c b/02-TeenyTinyShell/ttsh.c index 88992a2..c5e7f86 100644 --- a/02-TeenyTinyShell/ttsh.c +++ b/02-TeenyTinyShell/ttsh.c @@ -11,9 +11,14 @@ #include #include #include +#include +#include +#include +#include #define INPUT_MAX 256 #define CMD_MAX 5 +#define ARG_MAX 10 /* read_cmd_string() * Reads a line of text from the user @@ -76,41 +81,58 @@ int main() // TODO need to be able to get input from // the user in a loop + while(quit_flag == 0) { - // Print the input prompt - printf("$> "); + // Print the input prompt + printf("$> "); - // Read user input - if (read_cmd_string(user_input) == -1) - { - return 1; + // Read user input + if (read_cmd_string(user_input) == -1) + { + return 1; + } + + // TODO: Figure out how to handle the 'quit' command + if (strcmp(user_input, "quit") == 0){ + printf("Quitting...\n"); + quit_flag = 1; + } + + + // Chop the input into command strings + int cmd_count = parse_commands(user_input, cmd_strs); + if (cmd_count == -1) + { + return 1; + } + + // Chop the commands into arguments and execute one at a time + for (int i = 0; i < cmd_count; i++) { + + char **args = malloc(ARG_MAX*sizeof(char *)); + char* str = malloc(10*sizeof(char)); + strncpy(str, strtok(cmd_strs[i], " "), 10); + int j = 0; + while(str != NULL) { + args[j] = malloc(10*sizeof(char)); + strcpy(args[j], str); + str = strtok(NULL, " "); + j++; + } + pid_t pid = fork(); + + if(pid == 0) { + execvp(args[0], args); + printf("Command not found: %s\n", args[0]); + perror("Exec failed"); + exit(1); + } else if(pid > 0) { + waitpid(pid, NULL, 0); + } else { + printf("Fork failed\n"); + exit(1); + } + } } - - // TODO: Figure out how to handle the 'quit' command - if (strcmp(user_input, "quit") == 0){ - printf("Quitting..."); - exit(0); - } - - - // Chop the input into command strings - int cmd_count = parse_commands(user_input, cmd_strs); - if (cmd_count == -1) - { - return 1; - } - - // Chop the commands into arguments and execute one at a time - for (int i = 0; i < cmd_count; i++) - { - // TODO: - // 1) Chop the command into command line arguments - // need to handle up to 10 arguments - // NOTE: the command name is always the first argument - // 2) fork a process - // 3) execute the command with execvp - - } - return 0; } diff --git a/02-TeenyTinyShell/ttsh.o b/02-TeenyTinyShell/ttsh.o index 1aab76aef04e54a6085a57e22513915608977b6f..bdd73582f96ad8709e135d7bd54a0ce9b5219f26 100644 GIT binary patch literal 10640 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 e2Ido;L3xr@`CmELC{{@SB#-}0UXwLs{r>