use raw mode for linux so that I can later implement history and such. also update msh_read_input doc because i think it's gonna return more stuff soon

This commit is contained in:
IoIxD 2026-01-20 17:09:58 -07:00
commit fb3e073565
6 changed files with 95 additions and 17 deletions

View file

@ -4,18 +4,24 @@
int hashes_calced = 0; int hashes_calced = 0;
int cd_hash = 0; int cd_hash = 0;
int exit_hash = 0;
int msh_try_builtin(char *cmd, char **args) { int msh_try_builtin(char *cmd, char **args) {
int hash = str_hash(cmd); int hash = str_hash(cmd);
if (hashes_calced == 0) { if (hashes_calced == 0) {
cd_hash = str_hash("cd"); cd_hash = str_hash("cd");
exit_hash = str_hash("exit");
hashes_calced = 1; hashes_calced = 1;
} }
if (hash == cd_hash) { if (hash == cd_hash) {
msh_builtin_cd(args[1]); msh_builtin_cd(args[1]);
return 1; return 1;
} }
if (hash == exit_hash) {
msh_exit_shell();
return 0;
}
return 0; return 0;
}; };

View file

@ -181,7 +181,7 @@ void msh_lexer_execute(msh_lexer *lexer) {
msh_deallocate(full_path); msh_deallocate(full_path);
} }
if (!exec_success) { if (!exec_success) {
msh_print_strings("msh: ", cmd, ": command not found\n", 0); msh_print_strings("msh: ", cmd, ": command not found\n\r", 0);
} }
msh_deallocate(args); msh_deallocate(args);

View file

@ -20,8 +20,10 @@ MSH_ENTRY_POINT {
while ((out = msh_read_input(buf, &sz, 2048)), !out) { while ((out = msh_read_input(buf, &sz, 2048)), !out) {
} }
if (*buf != '\0') {
msh_lexer_parse(lexer, buf, sz + 1); msh_lexer_parse(lexer, buf, sz + 1);
msh_lexer_execute(lexer); msh_lexer_execute(lexer);
}
// msh_execute(buf, args); // msh_execute(buf, args);

View file

@ -2,27 +2,54 @@
#include "../system.h" #include "../system.h"
#include "syscall.h" #include "syscall.h"
#include <linux/kd.h>
#include <signal.h> #include <signal.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/termios.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <termios.h>
char msh_path_seperator = '/'; char msh_path_seperator = '/';
int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n) { int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n) {
char ch; char ch = 0;
SIZE_TYPE sz; 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) {
/* return */
case '\r':
ptr[*size] = '\0';
SYSCALL(write, 1, "\n\r", 2);
return 1;
break;
/* backspace */
case '\177':
if (*size <= 0) {
return 0;
}
SYSCALL(write, 1, "\33[D \33[D", 7);
*size -= 1;
break;
}
}
}
if (*size >= n) { if (*size >= n) {
return 2; return 2;
} }
sz = (SIZE_TYPE)SYSCALL(read, 0, &ch, 1);
if (ch == '\n') {
*(ptr + *size) = '\0';
return 1;
} else {
*(ptr + *size) = ch;
*size += sz;
}
return 0; return 0;
}; };
@ -76,12 +103,18 @@ int msh_execute(char *cmd, char **args) {
siginfo_t info; siginfo_t info;
SYSCALL(waitid, P_ALL, 0, &info, WEXITED); SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
SYSCALL(kill, fork, SIGKILL); SYSCALL(kill, fork, SIGKILL);
SYSCALL(write, 1, "\r", 2);
return info.si_code; return info.si_code;
} }
return 0; return 0;
}; };
void msh_exit_shell() { SYSCALL(exit, 0); }; void msh_exit_shell() {
msh_backend_deinit();
SYSCALL(exit, 0);
};
msh_file *msh_file_open(const char *file) { msh_file *msh_file_open(const char *file) {
msh_file *f = msh_allocate(sizeof(struct msh_file_t)); msh_file *f = msh_allocate(sizeof(struct msh_file_t));
@ -139,6 +172,37 @@ int msh_path_is_directory(char *path) {
return S_ISDIR(path_stat.st_mode); return S_ISDIR(path_stat.st_mode);
}; };
void msh_backend_init() { msh_linux_env_map_init(); }; static struct termios kbmode_og;
static struct termios ttsmode_og;
static struct termios ttsmode;
void msh_backend_deinit() { msh_linux_env_map_deinit(); }; void msh_linux_start_input_capture() {
SYSCALL(ioctl, 0, KDGKBMODE, &kbmode_og);
SYSCALL(ioctl, 0, TCGETS, &ttsmode_og);
SYSCALL(ioctl, 0, TCGETS, &ttsmode);
ttsmode.c_iflag &=
~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
ttsmode.c_oflag &= ~OPOST;
ttsmode.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
ttsmode.c_cflag &= ~(CSIZE | PARENB);
ttsmode.c_cflag |= CS8;
SYSCALL(ioctl, 0, TCSETSW, &ttsmode);
SYSCALL(ioctl, 0, KDSKBMODE, K_RAW);
};
void msh_linux_end_input_capture() {
SYSCALL(ioctl, 0, TCSETSW, &ttsmode_og);
SYSCALL(ioctl, 0, KDSKBMODE, &kbmode_og);
};
void msh_backend_init() {
msh_linux_env_map_init();
msh_linux_start_input_capture();
};
void msh_backend_deinit() {
msh_linux_env_map_deinit();
msh_linux_end_input_capture();
};

View file

@ -8,6 +8,9 @@ void msh_linux_print_errno(int errno);
void msh_linux_env_map_init(); void msh_linux_env_map_init();
void msh_linux_env_map_deinit(); void msh_linux_env_map_deinit();
void msh_linux_start_input_capture();
void msh_linux_end_input_capture();
struct msh_file_t { struct msh_file_t {
int fd; int fd;
}; };

View file

@ -59,7 +59,10 @@ void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n);
/* /*
* Read user input into ptr, stopping if it has reached n characters. * Read user input into ptr, stopping if it has reached n characters.
* returns 1 if finished reading, 2 if it ran out of space. * Also responsible for handling backspace.
* RETURNS:
* - 1 if finished reading
* - 2 if it ran out of space.
*/ */
int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n); int msh_read_input(char *ptr, SIZE_TYPE *size, SIZE_TYPE n);