Compare commits
4 commits
0068e8da25
...
313d344212
| Author | SHA1 | Date | |
|---|---|---|---|
| 313d344212 | |||
| 4814482cb2 | |||
| 0fff4a10c3 | |||
| 6fd2ff9ecf |
6 changed files with 215 additions and 121 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;
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +195,8 @@ void 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) {
|
||||||
|
|
@ -213,5 +215,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);
|
||||||
|
|
||||||
|
|
|
||||||
148
src/main.c
148
src/main.c
|
|
@ -1,82 +1,94 @@
|
||||||
#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();
|
||||||
|
|
||||||
lexer = msh_lexer_new();
|
ctx.lexer = msh_lexer_new();
|
||||||
|
|
||||||
while (1) {
|
ctx.result_str[0] = '0';
|
||||||
int out;
|
|
||||||
char buf[513];
|
|
||||||
int i = 0, n = 0, last = 0;
|
|
||||||
SIZE_TYPE sz = 0, leftoff = 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) {
|
msh_lexer_free(&ctx.lexer);
|
||||||
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,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,48 +14,122 @@
|
||||||
#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 = '/';
|
||||||
|
|
||||||
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)) {
|
||||||
char ch = 0;
|
for (;;) {
|
||||||
SIZE_TYPE sz = 0;
|
char ch = 0;
|
||||||
while (ch == 0) {
|
SIZE_TYPE sz = 0;
|
||||||
sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1);
|
while (ch == 0) {
|
||||||
/* don't write control characters or add them to the buffer */
|
sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1);
|
||||||
if (ch >= 0x20 && ch <= 0x7E) {
|
/* don't write control characters or add them to the buffer */
|
||||||
ptr[*size] = ch;
|
if (ch >= 0x20 && ch <= 0x7E) {
|
||||||
SYSCALL(write, 1, &ch, 1);
|
ptr[*size] = ch;
|
||||||
*size += sz;
|
SYSCALL(write, 1, &ch, 1);
|
||||||
} else {
|
*size += sz;
|
||||||
switch (ch) {
|
} else {
|
||||||
/* left/right arrow */
|
switch (ch) {
|
||||||
case '\033':
|
/* left/right arrow */
|
||||||
SYSCALL(read, 0, &ch, 1);
|
case '\033':
|
||||||
if (ch == '[') {
|
|
||||||
SYSCALL(read, 0, &ch, 1);
|
SYSCALL(read, 0, &ch, 1);
|
||||||
switch (ch) {
|
if (ch == '[') {
|
||||||
case 'C':
|
SYSCALL(read, 0, &ch, 1);
|
||||||
return -4;
|
switch (ch) {
|
||||||
case 'D':
|
case 'C':
|
||||||
return -3;
|
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) {
|
if (*size >= n) {
|
||||||
return -2;
|
f(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ch;
|
f(ch);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void msh_move_cursor(signed int offset) {
|
void msh_move_cursor(signed int offset) {
|
||||||
|
|
@ -112,22 +187,35 @@ 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);
|
SYSCALL(wait4, fork, &status, 0, &ru);
|
||||||
|
|
||||||
SYSCALL(kill, fork, SIGKILL);
|
SYSCALL(kill, fork, SIGKILL);
|
||||||
|
|
||||||
SYSCALL(write, 1, "\r", 2);
|
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;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
@ -153,11 +241,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);
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,12 @@ 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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read user input into ptr, stopping if it has reached n characters.
|
* Starts a loop that executes the given function whenever an action that
|
||||||
* RETURNS:
|
* necessitates it (i.e. terminal input) happens. On that note, it also reads
|
||||||
* * -1 = if finished reading
|
* input (up to n characters) into pointer you give it.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
@ -72,7 +75,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
|
||||||
*/
|
*/
|
||||||
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.
|
* Move terminal cursor x characters to the right. Pass in negative to go left.
|
||||||
|
|
|
||||||
|
|
@ -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