diff --git a/WEEK-6/dshlib.c b/WEEK-6/dshlib.c new file mode 100644 index 0000000000000000000000000000000000000000..ce5fdc1789767e636faeaa9830c426b86b763bb5 --- /dev/null +++ b/WEEK-6/dshlib.c @@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/wait.h> +#include "dshlib.h" + +/* Function to execute built-in commands */ +Built_In_Cmds exec_built_in_cmd(cmd_buff_t *cmd) { + if (strcmp(cmd->argv[0], "exit") == 0) { + exit(0); + } + else if (strcmp(cmd->argv[0], "cd") == 0) { + if (cmd->argc == 1) { + // If no argument, change to home directory + const char *home = getenv("HOME"); + if (home) { + if (chdir(home) != 0) { + perror("cd"); + } + } + } + else { + if (chdir(cmd->argv[1]) != 0) { + perror("cd"); + } + } + return BI_EXECUTED; + } + else if (strcmp(cmd->argv[0], "echo") == 0) { + for (int i = 1; i < cmd->argc; i++) { + // Remove surrounding quotes if present + char *arg = cmd->argv[i]; + if (arg[0] == '"' && arg[strlen(arg) - 1] == '"') { + arg[strlen(arg) - 1] = '\0'; // Remove trailing quote + printf("%s", arg + 1); // Print without leading quote + } else { + printf("%s", arg); + } + if (i < cmd->argc - 1) printf(" "); + } + printf("\n"); + return BI_EXECUTED; + } + + return BI_NOT_BI; +} + +/* Function to execute external commands */ +int exec_cmd(cmd_buff_t *cmd) { + pid_t pid = fork(); + + if (pid < 0) { + perror("Fork failed"); + return ERR_EXEC_CMD; + } + else if (pid == 0) { + if (execvp(cmd->argv[0], cmd->argv) == -1) { + perror("Command execution failed"); + exit(EXIT_FAILURE); + } + } + else { + int status; + waitpid(pid, &status, 0); + } + return OK; +} + +/* Function to parse user input into cmd_buff_t */ +int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd) { + cmd->argc = 0; + cmd->_cmd_buffer = strdup(cmd_line); + + if (!cmd->_cmd_buffer) { + return ERR_MEMORY; + } + + char *token = strtok(cmd->_cmd_buffer, " "); + while (token != NULL) { + cmd->argv[cmd->argc++] = token; + token = strtok(NULL, " "); + } + cmd->argv[cmd->argc] = NULL; // Null-terminate the argument list + + return OK; +} + +/* Main shell loop */ +int exec_local_cmd_loop() { + char input_buffer[SH_CMD_MAX]; + cmd_buff_t cmd; + + while (1) { + printf("%s", SH_PROMPT); + if (fgets(input_buffer, sizeof(input_buffer), stdin) == NULL) { + printf("\n"); + break; + } + + // Remove trailing newline + input_buffer[strcspn(input_buffer, "\n")] = '\0'; + + // Ignore empty input + if (strlen(input_buffer) == 0) { + continue; + } + + if (build_cmd_buff(input_buffer, &cmd) != OK) { + fprintf(stderr, "Error: command buffer allocation failed\n"); + continue; + } + + // Check if built-in command + if (exec_built_in_cmd(&cmd) == BI_NOT_BI) { + exec_cmd(&cmd); + } + + free(cmd._cmd_buffer); // Free allocated memory + } + return OK; +}