linux: handle programs crashing with segfault and such.

This commit is contained in:
IoIxD 2026-01-22 17:01:04 -07:00
commit 0fff4a10c3
5 changed files with 105 additions and 23 deletions

View file

@ -122,13 +122,13 @@ lexer_cancel:
return; return;
} }
void msh_lexer_execute(msh_lexer *lexer) { int msh_lexer_execute(msh_lexer *lexer) {
msh_lexer_item_list *list = lexer->item_list_head; msh_lexer_item_list *list = lexer->item_list_head;
char *cmd = list->item->str; char *cmd = list->item->str;
SIZE_TYPE cmd_size = list->item->strlen; SIZE_TYPE cmd_size = list->item->strlen;
SIZE_TYPE args_size = 0; 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; unsigned short i = 0, n = 0, j = 0, counter = 0;
char full_path[PATH_MAX]; char full_path[PATH_MAX];
char *args[512]; char *args[512];
@ -174,7 +174,7 @@ void msh_lexer_execute(msh_lexer *lexer) {
full_path[n++] = '\0'; full_path[n++] = '\0';
if (msh_path_exists(full_path)) { if (msh_path_exists(full_path)) {
msh_execute(full_path, args); exec_status = msh_execute(full_path, args);
exec_success = 1; exec_success = 1;
break; break;
} }
@ -192,9 +192,12 @@ void msh_lexer_execute(msh_lexer *lexer) {
} }
if (!exec_success) { if (!exec_success) {
msh_print_strings("msh: ", cmd, ": command not found\n\r", 0); msh_print_strings("msh: ", cmd, ": command not found\n\r", 0);
return 0;
} }
msh_lexer_flush(lexer); msh_lexer_flush(lexer);
return exec_status == 0 ? exec_status : exec_success;
}; };
void msh_lexer_flush(msh_lexer *lexer) { void msh_lexer_flush(msh_lexer *lexer) {
@ -213,5 +216,4 @@ void msh_lexer_flush(msh_lexer *lexer) {
void msh_lexer_free(msh_lexer *lexer) { void msh_lexer_free(msh_lexer *lexer) {
msh_deallocate(lexer->path); msh_deallocate(lexer->path);
msh_deallocate(lexer->item_list_head); msh_deallocate(lexer->item_list_head);
msh_deallocate(lexer);
}; };

View file

@ -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_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); void msh_lexer_free(msh_lexer *lexer);

View file

@ -4,15 +4,18 @@
static struct { static struct {
msh_lexer lexer; msh_lexer lexer;
char buf[513]; char buf[513];
char result_str[16];
SIZE_TYPE sz; SIZE_TYPE sz;
SIZE_TYPE leftoff; SIZE_TYPE leftoff;
} ctx; } ctx = {0};
static void print_heading() { static void print_heading() {
msh_print_strings(msh_working_directory(), " %> ", 0); msh_print_strings("[", ctx.result_str, "] ", msh_working_directory(), " %> ",
0);
} }
static void loop_func(int action) { static void loop_func(int action) {
switch (action) { switch (action) {
/* backspace (also do this when we run out of space) */ /* backspace (also do this when we run out of space) */
case -2: case -2:
@ -52,9 +55,13 @@ static void loop_func(int action) {
ctx.buf[ctx.sz] = '\0'; ctx.buf[ctx.sz] = '\0';
if (*ctx.buf != '\0') { if (*ctx.buf != '\0') {
int ret;
msh_lexer_parse(&ctx.lexer, ctx.buf, ctx.sz + 1); msh_lexer_parse(&ctx.lexer, ctx.buf, ctx.sz + 1);
msh_lexer_execute(&ctx.lexer); ret = msh_lexer_execute(&ctx.lexer);
itoa(ret, ctx.result_str, 10);
} }
memset(ctx.buf, 0, sizeof(ctx.buf)); memset(ctx.buf, 0, sizeof(ctx.buf));
ctx.sz = 0; ctx.sz = 0;
ctx.leftoff = 0; ctx.leftoff = 0;
@ -75,6 +82,8 @@ MSH_ENTRY_POINT {
ctx.lexer = msh_lexer_new(); ctx.lexer = msh_lexer_new();
ctx.result_str[0] = '0';
print_heading(); print_heading();
msh_loop(ctx.buf, &ctx.sz, 512, loop_func); msh_loop(ctx.buf, &ctx.sz, 512, loop_func);

View file

@ -4,6 +4,7 @@
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/limits.h> #include <linux/limits.h>
#include <signal.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -13,6 +14,75 @@
#include <sys/termios.h> #include <sys/termios.h>
#include <sys/wait.h> #include <sys/wait.h>
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 = '/'; char msh_path_seperator = '/';
void msh_loop(char *ptr, SIZE_TYPE *size, SIZE_TYPE n, void (*f)(int action)) { void msh_loop(char *ptr, SIZE_TYPE *size, SIZE_TYPE n, void (*f)(int action)) {
@ -117,14 +187,14 @@ int msh_execute(char *cmd, char **args) {
return ret; return ret;
} else { } else {
siginfo_t status; int status;
struct rusage ru; struct rusage ru;
SIZE_TYPE ret; SIZE_TYPE ret;
char *status_str; char *status_str;
msh_linux_setup_signals(); msh_linux_setup_signals();
ret = (SIZE_TYPE)SYSCALL(waitid, P_ALL, fork, &status, WEXITED, &ru); ret = (SIZE_TYPE)SYSCALL(wait4, fork, &status, 0, &ru);
SYSCALL(kill, fork, SIGKILL); SYSCALL(kill, fork, SIGKILL);
@ -132,7 +202,18 @@ int msh_execute(char *cmd, char **args) {
msh_linux_start_input_capture(); msh_linux_start_input_capture();
return status.si_signo; char pid_str[16];
itoa(fork, pid_str, 10);
if (WIFSIGNALED(status)) {
msh_print_strings(pid_str, "\t", (char *)signal_table[WTERMSIG(status)],
"\t", cmd, "\r\n", 0);
return WTERMSIG(status);
} else if (WIFSTOPPED(status)) {
msh_print_strings(pid_str, "\tstopped\t", cmd, "\r\n", 0);
} else {
return WEXITSTATUS(status);
}
} }
return 0; return 0;
}; };
@ -158,11 +239,7 @@ msh_file msh_file_open(const char *file) {
return f; return f;
}; };
void msh_file_close(msh_file *file) { void msh_file_close(msh_file *file) { SYSCALL(close, file->__fd); };
SYSCALL(close, file->__fd);
msh_deallocate(file);
};
void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n) { void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n) {
SYSCALL(read, file->__fd, ptr, n); SYSCALL(read, file->__fd, ptr, n);

View file

@ -2,13 +2,7 @@
#include <stdarg.h> #include <stdarg.h>
void msh_print_string(char *str) { void msh_print_string(char *str) { msh_write(str, strlen(str)); }
int i = 0;
while (str[i] != '\0') {
msh_write(&str[i], 1);
i++;
}
}
void msh_print_strings(char *str, ...) { void msh_print_strings(char *str, ...) {
va_list va; va_list va;