diff --git a/Assignment-05/starter/dshlib.c b/Assignment-05/starter/dshlib.c
index 0e6738ed007037b9f293051f058931ad8cb98ced..4e869d1b3f8c2ad4b94aeb2121f069b12fe21b27 100644
--- a/Assignment-05/starter/dshlib.c
+++ b/Assignment-05/starter/dshlib.c
@@ -9,6 +9,174 @@
 
 #include "dshlib.h"
 
+int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) {
+    if (cmd_line == NULL || cmd_buff == NULL) {
+        return ERR_CMD_OR_ARGS_TOO_BIG;
+    }
+
+    char *original_line = strdup(cmd_line);
+    if (original_line == NULL) {
+        return ERR_MEMORY;
+    }
+
+    char *trimmed_line = original_line;
+    while (*trimmed_line == ' ') {
+        trimmed_line++;
+    }
+
+    size_t len = strlen(trimmed_line);
+    while (len > 0 && trimmed_line[len - 1] == ' ') {
+        trimmed_line[--len] = '\0';
+    }
+
+    cmd_buff->argc = 0;
+    cmd_buff->_cmd_buffer = original_line;
+
+    char *saveptr1;
+    char *token = strtok_r(trimmed_line, " ", &saveptr1);
+
+    while (token != NULL && cmd_buff->argc < CMD_ARGV_MAX) {
+        if (token[0] == '"' || token[0] == '\'') {
+            char *end_quote = strchr(token + 1, token[0]);
+            if (end_quote != NULL) {
+                *end_quote = '\0';
+                cmd_buff->argv[cmd_buff->argc++] = token + 1;
+                token = strtok_r(NULL, " ", &saveptr1);
+                continue;
+            }
+        }
+        cmd_buff->argv[cmd_buff->argc++] = token;
+        token = strtok_r(NULL, " ", &saveptr1);
+    }
+    cmd_buff->argv[cmd_buff->argc] = NULL;
+
+    return OK;
+}
+
+
+
+
+int execute_pipeline(command_list_t *cmd_list) {
+    int num_commands = cmd_list->num;
+    int pipefd[2];
+    int prev_pipe_read = -1;
+    pid_t pids[num_commands];
+
+    for (int i = 0; i < num_commands; i++) {
+        if (i < num_commands - 1) {
+            if (pipe(pipefd) == -1) {
+                perror("pipe");
+                return ERR_MEMORY;
+            }
+        }
+
+        pids[i] = fork();
+        if (pids[i] == -1) {
+            perror("fork");
+            return ERR_MEMORY;
+        }
+
+        if (pids[i] == 0) { 
+            if (prev_pipe_read != -1) {
+                dup2(prev_pipe_read, STDIN_FILENO);
+                close(prev_pipe_read);
+            }
+
+            if (i < num_commands - 1) {
+                dup2(pipefd[1], STDOUT_FILENO);
+                close(pipefd[1]);
+                close(pipefd[0]);
+            }
+
+            cmd_buff_t *cmd = &cmd_list->commands[i];
+            execvp(cmd->exe, cmd->argv);
+            perror("execvp");
+            exit(EXIT_FAILURE);
+        } else {
+            if (prev_pipe_read != -1) {
+                close(prev_pipe_read);
+            }
+
+            if (i < num_commands - 1) {
+                prev_pipe_read = pipefd[0];
+                close(pipefd[1]);
+            }
+        }
+    }
+
+    for (int i = 0; i < num_commands; i++) {
+        waitpid(pids[i], NULL, 0);
+    }
+
+    return OK;
+}
+
+int parse_pipeline(char *cmd_line, command_list_t *clist) {
+    if (cmd_line == NULL || clist == NULL) {
+        return ERR_CMD_OR_ARGS_TOO_BIG;
+    }
+
+    char *original_line = strdup(cmd_line);
+    if (original_line == NULL) {
+        return ERR_MEMORY; 
+    }
+
+    char *trimmed_line = original_line;
+    while (*trimmed_line == ' ') {
+        trimmed_line++;
+    }
+    size_t len = strlen(trimmed_line);
+    while (len > 0 && trimmed_line[len - 1] == ' ') {
+        trimmed_line[--len] = '\0';
+    }
+
+    int command_count = 0;
+    char *saveptr1, *saveptr2;
+    char *command = strtok_r(trimmed_line, PIPE_STRING, &saveptr1);
+
+    while (command != NULL && command_count < CMD_MAX) {
+        memset(&clist->commands[command_count], 0, sizeof(command_t));
+
+        char *token = strtok_r(command, " ", &saveptr2);
+        if (token != NULL) {
+            if (strlen(token) >= EXE_MAX) {
+                free(original_line);
+                return ERR_CMD_OR_ARGS_TOO_BIG;
+            }
+            strcpy(clist->commands[command_count].exe, token);
+
+            int arg_count = 0;
+            while ((token = strtok_r(NULL, " ", &saveptr2)) != NULL) {
+                if (arg_count >= ARG_MAX - 1) { 
+                    free(original_line);
+                    return ERR_CMD_OR_ARGS_TOO_BIG;
+                }
+                if (strlen(token) >= ARG_MAX) {
+                    free(original_line);
+                    return ERR_CMD_OR_ARGS_TOO_BIG;
+                }
+                strcpy(clist->commands[command_count].args[arg_count], token);
+                arg_count++;
+            }
+            clist->commands[command_count].args[arg_count] = NULL; 
+        }
+
+        command_count++;
+        command = strtok_r(NULL, PIPE_STRING, &saveptr1);
+    }
+
+    if (command != NULL) {
+        // Too many commands
+        free(original_line);
+        return ERR_TOO_MANY_COMMANDS;
+    }
+
+    clist->num = command_count;
+    free(original_line); 
+    return OK;
+}
+
+
 /*
  * Implement your exec_local_cmd_loop function by building a loop that prompts the 
  * user for input.  Use the SH_PROMPT constant from dshlib.h and then
@@ -52,8 +220,90 @@
  *  Standard Library Functions You Might Want To Consider Using (assignment 2+)
  *      fork(), execvp(), exit(), chdir()
  */
-int exec_local_cmd_loop()
-{
-   
-    return OK;
+
+ int exec_local_cmd_loop() {
+    char cmd_buff[SH_CMD_MAX];
+    int rc = OK;
+
+    while (1) {
+        printf("%s", SH_PROMPT);
+
+        if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) {
+            printf("\n");
+            break; 
+        }
+
+        cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
+
+        if (strlen(cmd_buff) == 0) {
+            printf("%s\n", CMD_WARN_NO_CMD);
+            rc = WARN_NO_CMDS;
+            continue;
+        }
+
+        if (strstr(cmd_buff, "|") != NULL) {
+            command_list_t cmd_list;
+            if (parse_pipeline(cmd_buff, &cmd_list) != OK) {
+                fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
+                rc = ERR_TOO_MANY_COMMANDS;
+                continue;
+            }
+
+            if (execute_pipeline(&cmd_list) != OK) {
+                fprintf(stderr, "%s\n", CMD_ERR_EXECUTE);
+                rc = ERR_MEMORY;
+            }
+
+            free_command_list(&cmd_list);
+        } else {
+            cmd_buff_t cmd;
+            if (build_cmd_buff(cmd_buff, &cmd) != OK) {
+                fprintf(stderr, "%s\n", CMD_ERR_EXECUTE);
+                rc = ERR_MEMORY;
+                continue;
+            }
+
+            if (strcmp(cmd.argv[0], EXIT_CMD) == 0) {
+                free(cmd._cmd_buffer); 
+                break; 
+            }
+
+            if (strcmp(cmd.argv[0], "cd") == 0) {
+                if (cmd.argc == 1) {
+                    chdir(getenv("HOME"));
+                } else if (cmd.argc == 2) {
+                    if (chdir(cmd.argv[1]) != 0) {
+                        perror("cd");
+                    }
+                } else {
+                    fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
+                }
+                free(cmd._cmd_buffer);
+                continue;
+            }
+
+            pid_t pid = fork();
+            if (pid < 0) {
+                perror("fork failed");
+                rc = ERR_MEMORY;
+            } else if (pid == 0) {
+                execvp(cmd.argv[0], cmd.argv);
+                perror("execvp failed");
+                exit(EXIT_FAILURE); 
+            } else {
+                int status;
+                wait(&status);
+
+                if (WIFEXITED(status)) {
+                    if (WEXITSTATUS(status) != 0) {
+                        fprintf(stderr, "Command failed with exit code %d\n", WEXITSTATUS(status));
+                    }
+                }
+            }
+
+            free(cmd._cmd_buffer);
+        }
+    }
+
+    return rc;
 }