#include #include #include #include #include #include #include #include #include #define P_ALL 0 #define P_PID 1 #define P_PGID 2 #define P_PIDFD 3 #if !WEXITED #define WEXITED 0x00000004 #endif void parseInput(char *input, char *command, char **argv) { bool reachedArgv = false; char arg[32] = {0}; int idx = 0; int argvIdx = 1; for (int i = 0; i < strlen(input); i++) { char *a = {&(input[i])}; if (reachedArgv) { if (input[i] == ' ') { arg[idx] = '\0'; argv[argvIdx] = strdup(arg); memset(arg, 0, sizeof(arg)); argvIdx++; idx = 0; continue; } arg[idx] = input[i]; idx++; continue; } if (input[i] == ' ') { arg[idx] = '\0'; strcpy(command, arg); reachedArgv = true; memset(arg, 0, sizeof(arg)); idx = 0; continue; } arg[idx] = input[i]; idx++; } argv[0] = command; if (reachedArgv) { arg[idx] = '\0'; argv[argvIdx] = strdup(arg); } else { arg[idx] = '\0'; strcpy(command, arg); } } void joinPath(char *result, const char *base, const char *rel) { strcpy(result, base); strcat(result, "/"); strcat(result, rel); } int main() { char input[255] = {0}; char command[128] = {0}; char *argv[32] = {0}; char *env[32] = {"PATH=/bin"}; char path[128] = "/"; while (!false) { memset(input, 0, sizeof(input)); memset(command, 0, sizeof(command)); memset(argv, 0, sizeof(argv)); write(1, path, strlen(path)); write(1, " $ ", 3); int len = read(1, input, sizeof(input)); input[len - 1] = '\0'; parseInput(input, command, argv); if (!strcmp(command, "cd")) { char newpath[128] = {0}; char newresolvedpath[128] = {0}; if (argv[1][0] == '/') { strcpy(newresolvedpath, argv[1]); } else { joinPath(newpath, path, argv[1]); realpath(newpath, newresolvedpath); } if (!access(newresolvedpath, F_OK)) { struct stat statResult; stat(newresolvedpath, &statResult); if (S_ISDIR(statResult.st_mode)) { strcpy(path, newresolvedpath); } else { write(1, "uuuuh das not a dir\n", 21); } } else { write(1, "uuuuh das not a dir\n", 21); } continue; } __pid_t forkResult = fork(); if (forkResult == 0) { execve(command, argv, 0); } else { waitid(P_ALL, 0, 0, WEXITED); } } }