#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;
}