#include #include #include #include #include #include "array.h" #include void print_prompt(); int parse_line(char const *line, char **exe, char ***parts, size_t *part_count); // returns the return code of the executed program int exec_command(const char *path, char *const argv[], unsigned timeout); int main(int argc, char* argv[]) { while (true) { char *line = NULL; size_t cap = 0; size_t length = 0; print_prompt(); if ((length = getline(&line, &cap, stdin)) < 0) { fprintf(stderr, "Failed to read from STDIN"); exit(-1); } line[length - 1] = '\0'; // cut the line feed char *exe = NULL; char **arguments = NULL; size_t argument_count; parse_line(line, &exe, &arguments, &argument_count); if (strcmp(exe, "cd") == 0) { printf("Changing dirs \n"); chdir("beispiele"); } else if (strcmp(exe, "exit") == 0) { exit(0); } else { exec_command(exe, arguments, 0); } free((void *)line); // no need to free exe, since it is part of arguments any way arrayRelease(arguments); } } int parse_line(char const *line, char **exe, char ***parts, size_t *part_count) { char *part; char **local_parts; if (arrayInit(part) != 0 || arrayInit(local_parts) != 0) { fprintf(stderr, "Failed to prepare new part array"); exit(-1); } bool found_exe = false; char c; int i = 0; while (true) { c = line[i++]; if (c == ' ' || c == '\0') { arrayPush(part) = '\0'; arrayPush(local_parts) = part; if (!found_exe) { // the first is the executable *exe = malloc(arrayLen(part) * sizeof(char)); strcpy(*exe, part); found_exe = true; } arrayInit(part); if (c == '\0') { arrayPush(local_parts) = NULL; break; } } else { arrayPush(part) = c; } } *part_count = arrayLen(local_parts); *parts = local_parts; return 0; } void print_prompt() { size_t length = 1024; char *buffer = malloc(length * sizeof(char)); getcwd(buffer, length); if (buffer == NULL) { printf(".> "); } else { printf("%s > ", buffer); } } int exec_command(const char *path, char *const argv[], unsigned timeout) { int pid; int pipefd[2]; int status; char buf[512]; pipe(pipefd); if ((pid = fork()) == 0) { close(pipefd[0]); dup2(pipefd[1], 1); // includes close(1); close(pipefd[1]); execvp(path, argv); fprintf(stderr, "no program\n"); exit(-1); } if (pid < 0) { fprintf(stderr, "no fork\n"); exit(-2); } close(pipefd[1]); size_t length = 0; while ((length = read(pipefd[0], buf, 10)) > 0) { buf[length] = '\0'; printf("%s", buf); } waitpid(pid, &status, 0); close(pipefd[0]); return WEXITSTATUS(status); }