diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 79bbe49..89f2513 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -122,13 +122,13 @@ lexer_cancel: return; } -void msh_lexer_execute(msh_lexer *lexer) { +int msh_lexer_execute(msh_lexer *lexer) { msh_lexer_item_list *list = lexer->item_list_head; char *cmd = list->item->str; SIZE_TYPE cmd_size = list->item->strlen; SIZE_TYPE args_size = 0; - char is_first_arg = 0, exec_success = 0; + char is_first_arg = 0, exec_success = 0, exec_status = 0; unsigned short i = 0, n = 0, j = 0, counter = 0; char full_path[PATH_MAX]; char *args[512]; @@ -174,7 +174,7 @@ void msh_lexer_execute(msh_lexer *lexer) { full_path[n++] = '\0'; if (msh_path_exists(full_path)) { - msh_execute(full_path, args); + exec_status = msh_execute(full_path, args); exec_success = 1; break; } @@ -195,6 +195,8 @@ void msh_lexer_execute(msh_lexer *lexer) { } msh_lexer_flush(lexer); + + return exec_status == 0 ? exec_status : exec_success; }; void msh_lexer_flush(msh_lexer *lexer) { @@ -213,5 +215,4 @@ void msh_lexer_flush(msh_lexer *lexer) { void msh_lexer_free(msh_lexer *lexer) { msh_deallocate(lexer->path); msh_deallocate(lexer->item_list_head); - msh_deallocate(lexer); }; diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index c3aed3c..b5da7cb 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -38,7 +38,7 @@ void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, char *buf, void msh_lexer_flush(msh_lexer *lexer); -void msh_lexer_execute(msh_lexer *lexer); +int msh_lexer_execute(msh_lexer *lexer); void msh_lexer_free(msh_lexer *lexer); diff --git a/src/main.c b/src/main.c index 37631a7..495f4af 100644 --- a/src/main.c +++ b/src/main.c @@ -1,82 +1,94 @@ #include "lexer/lexer.h" #include "system/system.h" +static struct { + msh_lexer lexer; + char buf[513]; + char result_str[16]; + SIZE_TYPE sz; + SIZE_TYPE leftoff; +} ctx = {0}; + +static void print_heading() { + msh_print_strings("[", ctx.result_str, "] ", msh_working_directory(), " %> ", + 0); +} + +static void loop_func(int action) { + + switch (action) { + /* backspace (also do this when we run out of space) */ + case -2: + case 0x7F: + if (ctx.sz > 0) { + msh_move_cursor(-1); + msh_write(" ", 1); + msh_move_cursor(-1); + ctx.buf[ctx.sz--] = '\0'; + } + break; + /* Ctrl-C */ + case 0x3: + msh_print_string("^C\n\r"); + return; + /* left */ + case -3: + if (ctx.sz > 0) { + msh_move_cursor(-1); + --ctx.sz; + ++ctx.leftoff; + } + break; + /* right */ + case -4: + if (ctx.leftoff > 0) { + msh_move_cursor(1); + --ctx.leftoff; + } + if (ctx.sz < 2048) { + ++ctx.sz; + } + break; + /* execute */ + case -1: + ctx.sz += ctx.leftoff; + ctx.buf[ctx.sz] = '\0'; + + if (*ctx.buf != '\0') { + int ret; + msh_lexer_parse(&ctx.lexer, ctx.buf, ctx.sz + 1); + ret = msh_lexer_execute(&ctx.lexer); + + itoa(ret, ctx.result_str, 10); + } + + memset(ctx.buf, 0, sizeof(ctx.buf)); + ctx.sz = 0; + ctx.leftoff = 0; + + print_heading(); + break; + default: + if (ctx.leftoff > 0) { + --ctx.leftoff; + } + break; + } +} + /* Makefile-defined system entry point. */ MSH_ENTRY_POINT { - msh_lexer lexer; - msh_backend_init(); - lexer = msh_lexer_new(); + ctx.lexer = msh_lexer_new(); - while (1) { - int out; - char buf[513]; - int i = 0, n = 0, last = 0; - SIZE_TYPE sz = 0, leftoff = 0; + ctx.result_str[0] = '0'; - memset(buf, 0, sizeof(buf)); + print_heading(); - msh_print_strings(msh_working_directory(), " %> ", 0); + msh_loop(ctx.buf, &ctx.sz, 512, loop_func); - while ((out = msh_read_input(buf, &sz, 512)), out != -1) { - switch (out) { - /* backspace (also do this when we run out of space) */ - case -2: - case 0x7F: - if (sz > 0) { - msh_move_cursor(-1); - msh_write(" ", 1); - msh_move_cursor(-1); - buf[sz--] = '\0'; - } - break; - /* Ctrl-C */ - case 0x3: - msh_print_string("^C\n\r"); - goto end_loop; - break; - /* left */ - case -3: - if (sz > 0) { - msh_move_cursor(-1); - --sz; - ++leftoff; - } - break; - /* right */ - case -4: - if (leftoff > 0) { - msh_move_cursor(1); - --leftoff; - } - if (sz < 2048) { - ++sz; - } - break; - default: - if (leftoff > 0) { - --leftoff; - } - break; - } - } - - sz += leftoff; - buf[sz] = '\0'; - - if (*buf != '\0') { - msh_lexer_parse(&lexer, buf, sz + 1); - msh_lexer_execute(&lexer); - } - - // msh_execute(buf, args); - - end_loop: - continue; - } - - msh_lexer_free(&lexer); + msh_lexer_free(&ctx.lexer); msh_backend_deinit(); } diff --git a/src/system/linux/linux.c b/src/system/linux/linux.c index 26498ee..4444cc1 100644 --- a/src/system/linux/linux.c +++ b/src/system/linux/linux.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -13,48 +14,122 @@ #include #include +static const char *signal_table[] = { + "Hangup", + "Interrupt", + "Quit", + "Illegal instruction", + "Trace/breakpoint trap", + "Aborted", + "(Same value as SIGABRT) Aborted", + "Bus error", + "Floating point exception", + "Killed", + "User defined signal 1", + "Segmentation fault", + "User defined signal 2", + "Broken pipe", + "Alarm clock", + "Terminated", + "Stack fault", + "Child exited", + "(Same value as SIGCHLD) Child exited", + "Continued", + "Stopped (signal)", + "Stopped", + "Stopped (tty input)", + "Stopped (tty output)", + "Urgent I/O condition", + "CPU time limit exceeded", + "File size limit exceeded", + "Virtual timer expired", + "Profiling timer expired", + "Window changed", + "I/O possible", + "(Same value as SIGPOLL) I/O possible", + "Power failure", + "Bad system call", + "Real-time signal reserved by the C library for NPTL ; see signal(7)", + "Real-time signal reserved by the C library for NPTL ; see signal(7)", + "Real-time signal 0", + "Real-time signal 1", + "Real-time signal 2", + "Real-time signal 3", + "Real-time signal 4", + "Real-time signal 5", + "Real-time signal 6", + "Real-time signal 7", + "Real-time signal 8", + "Real-time signal 9", + "Real-time signal 10", + "Real-time signal 11", + "Real-time signal 12", + "Real-time signal 13", + "Real-time signal 14", + "Real-time signal 15", + "Real-time signal 16", + "Real-time signal 17", + "Real-time signal 18", + "Real-time signal 19", + "Real-time signal 20", + "Real-time signal 21", + "Real-time signal 22", + "Real-time signal 23", + "Real-time signal 24", + "Real-time signal 25", + "Real-time signal 26", + "Real-time signal 27", + "Real-time signal 28", + "Real-time signal 29", + "Real-time signal 30"}; + char msh_path_seperator = '/'; -int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n) { - char ch = 0; - SIZE_TYPE sz = 0; - while (ch == 0) { - sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1); - /* don't write control characters or add them to the buffer */ - if (ch >= 0x20 && ch <= 0x7E) { - ptr[*size] = ch; - SYSCALL(write, 1, &ch, 1); - *size += sz; - } else { - switch (ch) { - /* left/right arrow */ - case '\033': - SYSCALL(read, 0, &ch, 1); - if (ch == '[') { +void msh_loop(char *ptr, SIZE_TYPE *size, SIZE_TYPE n, void (*f)(int action)) { + for (;;) { + char ch = 0; + SIZE_TYPE sz = 0; + while (ch == 0) { + sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1); + /* don't write control characters or add them to the buffer */ + if (ch >= 0x20 && ch <= 0x7E) { + ptr[*size] = ch; + SYSCALL(write, 1, &ch, 1); + *size += sz; + } else { + switch (ch) { + /* left/right arrow */ + case '\033': SYSCALL(read, 0, &ch, 1); - switch (ch) { - case 'C': - return -4; - case 'D': - return -3; + if (ch == '[') { + SYSCALL(read, 0, &ch, 1); + switch (ch) { + case 'C': + f(-4); + break; + case 'D': + f(-3); + break; + } } + break; + /* return */ + case '\r': + SYSCALL(write, 1, "\n\r", 2); + f(-1); + break; + default: + break; } - break; - /* return */ - case '\r': - SYSCALL(write, 1, "\n\r", 2); - return -1; - default: - break; } } - } - if (*size >= n) { - return -2; - } + if (*size >= n) { + f(-2); + } - return ch; + f(ch); + } }; void msh_move_cursor(signed int offset) { @@ -112,22 +187,35 @@ int msh_execute(char *cmd, char **args) { return ret; } else { - siginfo_t status; + int status; struct rusage ru; SIZE_TYPE ret; char *status_str; msh_linux_setup_signals(); - ret = (SIZE_TYPE)SYSCALL(waitid, P_ALL, fork, &status, WEXITED, &ru); + SYSCALL(wait4, fork, &status, 0, &ru); SYSCALL(kill, fork, SIGKILL); SYSCALL(write, 1, "\r", 2); - msh_linux_start_input_capture(); + char pid_str[16]; + itoa(fork, pid_str, 10); - return status.si_signo; + if (WIFSIGNALED(status)) { + msh_print_strings(pid_str, " ", (char *)signal_table[WTERMSIG(status)], + " ", cmd, "\n\r", 0); + ret = WTERMSIG(status); + } else if (WIFSTOPPED(status)) { + msh_print_strings(pid_str, "\tstopped\t", cmd, "\n\r", 0); + ret = WEXITSTATUS(status); + } else { + ret = WEXITSTATUS(status); + } + + msh_linux_start_input_capture(); + return ret; } return 0; }; @@ -153,11 +241,7 @@ msh_file msh_file_open(const char *file) { return f; }; -void msh_file_close(msh_file *file) { - SYSCALL(close, file->__fd); - - msh_deallocate(file); -}; +void msh_file_close(msh_file *file) { SYSCALL(close, file->__fd); }; void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n) { SYSCALL(read, file->__fd, ptr, n); diff --git a/src/system/system.h b/src/system/system.h index 2d43129..9961016 100644 --- a/src/system/system.h +++ b/src/system/system.h @@ -62,9 +62,12 @@ int msh_path_is_directory(char *path); void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n); /* - * Read user input into ptr, stopping if it has reached n characters. - * RETURNS: - * * -1 = if finished reading + * Starts a loop that executes the given function whenever an action that + * necessitates it (i.e. terminal input) happens. On that note, it also reads + * input (up to n characters) into pointer you give it. + * + * ACTIONS: + * * * -1 = if finished reading * * -2 = if it ran out of space. * * -3 = left arrow * * -4 = right arrow @@ -72,7 +75,7 @@ void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n); * * -6 = ctrl right arrow * * 0 < ascii character */ -int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n); +void msh_loop(char *ptr, SIZE_TYPE *size, SIZE_TYPE n, void (*f)(int action)); /* * Move terminal cursor x characters to the right. Pass in negative to go left. diff --git a/src/util/string.c b/src/util/string.c index 419ca58..586f48e 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -2,13 +2,7 @@ #include -void msh_print_string(char *str) { - int i = 0; - while (str[i] != '\0') { - msh_write(&str[i], 1); - i++; - } -} +void msh_print_string(char *str) { msh_write(str, strlen(str)); } void msh_print_strings(char *str, ...) { va_list va;