/* * 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; } for (command *cmd = cmds; cmd; cmd = cmd->next) { pid_t result = execute_command(cmd); if (result < 0) { break; } } print_commands(stdout, cmds); for (command *cmd = cmds; cmd; cmd = cmd->next) { if (cmd->pid > 0) { fprintf(stderr, "Waiting for %d\n", cmd->pid); waitpid(cmd->pid, NULL, 0); fprintf(stderr, "%d completed\n", cmd->pid); } } free_tokens: destroy_tokens(parsed_cmd); free_commands: destroy_commands(cmds); draw_prompt: fprintf(stdout, "$ "); } }