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:
parent
efeeb73ef5
commit
fb3e073565
6 changed files with 95 additions and 17 deletions
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue