Compare commits
No commits in common. "313d3442126fbaf190b7de2fcc9393304407683c" and "0068e8da25b2a63c3b97ece720b0262e6123b632" have entirely different histories.
313d344212
...
0068e8da25
6 changed files with 121 additions and 215 deletions
|
|
@ -122,13 +122,13 @@ lexer_cancel:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int msh_lexer_execute(msh_lexer *lexer) {
|
void 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, exec_status = 0;
|
char is_first_arg = 0, exec_success = 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 @@ int 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)) {
|
||||||
exec_status = msh_execute(full_path, args);
|
msh_execute(full_path, args);
|
||||||
exec_success = 1;
|
exec_success = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -195,8 +195,6 @@ int msh_lexer_execute(msh_lexer *lexer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -215,4 +213,5 @@ 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);
|
||||||
|
|
||||||
int msh_lexer_execute(msh_lexer *lexer);
|
void msh_lexer_execute(msh_lexer *lexer);
|
||||||
|
|
||||||
void msh_lexer_free(msh_lexer *lexer);
|
void msh_lexer_free(msh_lexer *lexer);
|
||||||
|
|
||||||
|
|
|
||||||
148
src/main.c
148
src/main.c
|
|
@ -1,94 +1,82 @@
|
||||||
#include "lexer/lexer.h"
|
#include "lexer/lexer.h"
|
||||||
#include "system/system.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. */
|
/* Makefile-defined system entry point. */
|
||||||
MSH_ENTRY_POINT {
|
MSH_ENTRY_POINT {
|
||||||
|
msh_lexer lexer;
|
||||||
|
|
||||||
msh_backend_init();
|
msh_backend_init();
|
||||||
|
|
||||||
ctx.lexer = msh_lexer_new();
|
lexer = msh_lexer_new();
|
||||||
|
|
||||||
ctx.result_str[0] = '0';
|
while (1) {
|
||||||
|
int out;
|
||||||
|
char buf[513];
|
||||||
|
int i = 0, n = 0, last = 0;
|
||||||
|
SIZE_TYPE sz = 0, leftoff = 0;
|
||||||
|
|
||||||
print_heading();
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
msh_loop(ctx.buf, &ctx.sz, 512, loop_func);
|
msh_print_strings(msh_working_directory(), " %> ", 0);
|
||||||
|
|
||||||
msh_lexer_free(&ctx.lexer);
|
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_backend_deinit();
|
msh_backend_deinit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#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>
|
||||||
|
|
@ -14,122 +13,48 @@
|
||||||
#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)) {
|
int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n) {
|
||||||
for (;;) {
|
char ch = 0;
|
||||||
char ch = 0;
|
SIZE_TYPE sz = 0;
|
||||||
SIZE_TYPE sz = 0;
|
while (ch == 0) {
|
||||||
while (ch == 0) {
|
sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1);
|
||||||
sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1);
|
/* don't write control characters or add them to the buffer */
|
||||||
/* don't write control characters or add them to the buffer */
|
if (ch >= 0x20 && ch <= 0x7E) {
|
||||||
if (ch >= 0x20 && ch <= 0x7E) {
|
ptr[*size] = ch;
|
||||||
ptr[*size] = ch;
|
SYSCALL(write, 1, &ch, 1);
|
||||||
SYSCALL(write, 1, &ch, 1);
|
*size += sz;
|
||||||
*size += sz;
|
} else {
|
||||||
} else {
|
switch (ch) {
|
||||||
switch (ch) {
|
/* left/right arrow */
|
||||||
/* left/right arrow */
|
case '\033':
|
||||||
case '\033':
|
SYSCALL(read, 0, &ch, 1);
|
||||||
|
if (ch == '[') {
|
||||||
SYSCALL(read, 0, &ch, 1);
|
SYSCALL(read, 0, &ch, 1);
|
||||||
if (ch == '[') {
|
switch (ch) {
|
||||||
SYSCALL(read, 0, &ch, 1);
|
case 'C':
|
||||||
switch (ch) {
|
return -4;
|
||||||
case 'C':
|
case 'D':
|
||||||
f(-4);
|
return -3;
|
||||||
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) {
|
|
||||||
f(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
f(ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*size >= n) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
};
|
};
|
||||||
|
|
||||||
void msh_move_cursor(signed int offset) {
|
void msh_move_cursor(signed int offset) {
|
||||||
|
|
@ -187,35 +112,22 @@ int msh_execute(char *cmd, char **args) {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
int status;
|
siginfo_t 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();
|
||||||
|
|
||||||
SYSCALL(wait4, fork, &status, 0, &ru);
|
ret = (SIZE_TYPE)SYSCALL(waitid, P_ALL, fork, &status, WEXITED, &ru);
|
||||||
|
|
||||||
SYSCALL(kill, fork, SIGKILL);
|
SYSCALL(kill, fork, SIGKILL);
|
||||||
|
|
||||||
SYSCALL(write, 1, "\r", 2);
|
SYSCALL(write, 1, "\r", 2);
|
||||||
|
|
||||||
char pid_str[16];
|
|
||||||
itoa(fork, pid_str, 10);
|
|
||||||
|
|
||||||
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();
|
msh_linux_start_input_capture();
|
||||||
return ret;
|
|
||||||
|
return status.si_signo;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
@ -241,7 +153,11 @@ msh_file msh_file_open(const char *file) {
|
||||||
return f;
|
return f;
|
||||||
};
|
};
|
||||||
|
|
||||||
void msh_file_close(msh_file *file) { SYSCALL(close, file->__fd); };
|
void msh_file_close(msh_file *file) {
|
||||||
|
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);
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,9 @@ int msh_path_is_directory(char *path);
|
||||||
void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n);
|
void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts a loop that executes the given function whenever an action that
|
* Read user input into ptr, stopping if it has reached n characters.
|
||||||
* necessitates it (i.e. terminal input) happens. On that note, it also reads
|
* RETURNS:
|
||||||
* input (up to n characters) into pointer you give it.
|
* * -1 = if finished reading
|
||||||
*
|
|
||||||
* ACTIONS:
|
|
||||||
* * * -1 = if finished reading
|
|
||||||
* * -2 = if it ran out of space.
|
* * -2 = if it ran out of space.
|
||||||
* * -3 = left arrow
|
* * -3 = left arrow
|
||||||
* * -4 = right arrow
|
* * -4 = right arrow
|
||||||
|
|
@ -75,7 +72,7 @@ void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n);
|
||||||
* * -6 = ctrl right arrow
|
* * -6 = ctrl right arrow
|
||||||
* * 0 < ascii character
|
* * 0 < ascii character
|
||||||
*/
|
*/
|
||||||
void msh_loop(char *ptr, SIZE_TYPE *size, SIZE_TYPE n, void (*f)(int action));
|
int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move terminal cursor x characters to the right. Pass in negative to go left.
|
* Move terminal cursor x characters to the right. Pass in negative to go left.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,13 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
void msh_print_string(char *str) { msh_write(str, strlen(str)); }
|
void msh_print_string(char *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