linux: handle programs crashing with segfault and such.
This commit is contained in:
parent
6fd2ff9ecf
commit
0fff4a10c3
5 changed files with 105 additions and 23 deletions
|
|
@ -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);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
15
src/main.c
15
src/main.c
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue