From 06a02a3a50baf261a0f1c998bfd02269c3ed45de Mon Sep 17 00:00:00 2001 From: "Douglas B. Rumbaugh" Date: Fri, 31 Oct 2025 23:41:32 -0400 Subject: Initial commit --- src/hush.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/hush.c (limited to 'src/hush.c') diff --git a/src/hush.c b/src/hush.c new file mode 100644 index 0000000..478103f --- /dev/null +++ b/src/hush.c @@ -0,0 +1,106 @@ +/* + * hush -- the HU Shell + * + * A minimal shell for CISC 301, Operating Systems + * + */ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "lexer.h" +#include "command.h" + +FILE *open_input(int argc, char **argv) { + FILE *input_file = (argc > 1) ? fopen(argv[1], "r") : stdin; + if (!input_file) { + fprintf(stderr, "ERROR: Failed to open input file %s\n", argv[1]); + exit(EXIT_FAILURE); + } + + return input_file; +} + +static size_t get_command_len(char *cmdstr) { + size_t len = strlen(cmdstr); + if (cmdstr[len - 1] != '\n') { + len = 0; + } + + return len; +} + +int main(int argc, char **argv) { + FILE *input_file = open_input(argc, argv); + char buffer[MAX_LINE_LEN]; + + fprintf(stdout, "$ "); + while (fgets(buffer, MAX_LINE_LEN, input_file)) { + char *cmdstr = trim(buffer); + if (!cmdstr) { + fprintf(stderr, "ERROR: Specified command is too long\n"); + goto draw_prompt; + } + + if (strlen(cmdstr) == 0) { + goto draw_prompt; + } + + token *parsed_cmd; + if (!(parsed_cmd = parse_command(cmdstr))) { + fprintf(stderr, "ERROR: Failed to parse command\n"); + goto draw_prompt; + } + + { + token *error; + if ((error = validate_command(parsed_cmd))) { + fprintf(stderr, "ERROR: Invalid syntax near %s\n", error->text); + print_parsed_command(stdout, parsed_cmd); + goto free_tokens; + } + } + + // print_parsed_command(stdout, parsed_cmd); + + if (parsed_cmd->type == TKN_VARKEY) { + /* handle variable creation */ + goto free_tokens; + } + + size_t commands; + command *cmds; + if (!(cmds = commands_from_tokens(parsed_cmd, &commands ))) { + fprintf(stderr, "ERROR: Unable to create commands from tokens"); + goto free_tokens; + } + + // print_commands(stdout, cmds); + + for (command *cmd = cmds; cmd; cmd = cmd->next) { + pid_t result = execute_command(cmd); + if (result < 0) { + break; + } + } + + for (command *cmd = cmds; cmd; cmd = cmd->next) { + if (cmd->pid > 0) { + waitpid(cmd->pid, NULL, 0); + } + } + + free_tokens: + destroy_tokens(parsed_cmd); + + free_commands: + destroy_commands(cmds); + + draw_prompt: + fprintf(stdout, "$ "); + } +} -- cgit v1.2.3