#include #include #include #include #include #include #include #include "commands.h" #include "history.h" // Function declarations for builtin commands int cd(char **args); int help(char **args); int quit(char **args); int history(char **args); // List of builtin commands' names char *builtin_cmds[] = { "cd", "help", "exit", "history" }; int (*builtin_func[]) (char **) = { &cd, &help, &quit, // cant name it exit as it is taken &history }; // number of built in commands int num_builtins() { return sizeof(builtin_cmds) / sizeof(char *); } // change directory int cd(char **args) { if (args[1] == NULL) { char *home = getenv("HOME"); if (chdir(home) != 0) { perror("rush"); } } else { if (chdir(args[1]) != 0) { perror("rush"); } } return 1; } // show help menu int help(char **args) { printf("rush v0.01-alpha\n"); printf("Built in commands:\n"); for (int i = 0; i < num_builtins(); i++) { printf(" %s\n", builtin_cmds[i]); } printf("Use 'man' to read manual of programs\n"); printf("Licensed under GPL v3\n"); return 1; } int quit(char **args) { return 0; // exit prompting loop, which also the shell } int history(char **args) { char **history = get_all_history(); for (int i = 0; history[i] != NULL; ++i) { printf("%s\n", history[i]); free(history[i]); } free(history); return 1; } bool is_builtin(char *command) { for (int i = 0; i < num_builtins(); i++) { if (strcmp(command, builtin_cmds[i]) == 0) { return true; } } return false; } // execute built in commands or launch commands and wait it to terminate, return 1 to keep shell running int execute(char **args) { if (args[0] == NULL) { // An empty command was entered. return 1; } for (int i = 0; i < num_builtins(); i++) { if (strcmp(args[0], builtin_cmds[i]) == 0) { return (*builtin_func[i])(args); } } pid_t pid, wpid; int status; pid = fork(); if (pid == 0) { // Child process if (execvp(args[0], args) == -1) { if (errno == ENOENT) { fprintf(stderr, "rush: command not found: %s\n", args[0]); } } exit(EXIT_FAILURE); } else if (pid < 0) { perror("Cannot fork"); } else { // Parent process do { wpid = waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); } return 1; }