mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
terminal fixes
This commit is contained in:
parent
3fbcf3d4fd
commit
b40d3c050d
12 changed files with 149 additions and 28 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
|
|
@ -871,10 +871,12 @@ void cmd_screen_clear() {
|
|||
for(int c=0; c<terminal_cols; c++) {
|
||||
screen_buffer[r * terminal_cols + c].c = ' ';
|
||||
screen_buffer[r * terminal_cols + c].color = COLOR_DARK_TEXT;
|
||||
screen_buffer[r * terminal_cols + c].attrs = 0;
|
||||
}
|
||||
}
|
||||
cursor_row = 0;
|
||||
cursor_col = 0;
|
||||
wm_mark_dirty(win_cmd.x, win_cmd.y, win_cmd.w, win_cmd.h);
|
||||
}
|
||||
|
||||
// Public for CLI apps to use - exit/close the terminal window
|
||||
|
|
@ -1159,8 +1161,6 @@ void cmd_process_finished(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
extern int cursor_col;
|
||||
void cmd_putchar(char c);
|
||||
if (cursor_col > 0) {
|
||||
cmd_putchar('\n');
|
||||
}
|
||||
|
|
@ -2000,6 +2000,21 @@ void cmd_handle_click(Window *win, int x, int y) {
|
|||
}
|
||||
}
|
||||
|
||||
static void cmd_handle_close(Window *win) {
|
||||
if (!win) return;
|
||||
|
||||
extern process_t* process_get_by_ui_window(void *win);
|
||||
extern void process_terminate(process_t *proc);
|
||||
|
||||
// Find any process associated with this terminal window and terminate it
|
||||
process_t *proc = process_get_by_ui_window(win);
|
||||
if (proc) {
|
||||
process_terminate(proc);
|
||||
}
|
||||
|
||||
win->visible = false;
|
||||
}
|
||||
|
||||
void cmd_set_raw_mode(bool enabled) {
|
||||
terminal_raw_mode = enabled;
|
||||
}
|
||||
|
|
@ -2470,6 +2485,7 @@ void cmd_init(void) {
|
|||
win_cmd.handle_key = cmd_key;
|
||||
win_cmd.handle_click = cmd_handle_click;
|
||||
win_cmd.handle_right_click = NULL;
|
||||
win_cmd.handle_close = cmd_handle_close;
|
||||
win_cmd.handle_resize = cmd_handle_resize;
|
||||
win_cmd.resizable = true;
|
||||
|
||||
|
|
|
|||
BIN
src/kernel/images/.DS_Store
vendored
BIN
src/kernel/images/.DS_Store
vendored
Binary file not shown.
|
|
@ -272,6 +272,27 @@ int network_tcp_recv(void *buf, size_t max_len) {
|
|||
return (int)copied;
|
||||
}
|
||||
|
||||
int network_tcp_recv_nb(void *buf, size_t max_len) {
|
||||
if (network_processing) return -1;
|
||||
network_processing = 1;
|
||||
|
||||
if (!tcp_recv_queue) {
|
||||
network_processing = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t to_copy = max_len;
|
||||
if (to_copy > tcp_recv_queue->tot_len) to_copy = tcp_recv_queue->tot_len;
|
||||
if (to_copy > 0xFFFF) to_copy = 0xFFFF; // pbuf_copy_partial limit
|
||||
|
||||
size_t copied = pbuf_copy_partial(tcp_recv_queue, buf, (u16_t)to_copy, 0);
|
||||
struct pbuf *remainder = pbuf_free_header(tcp_recv_queue, (u16_t)copied);
|
||||
if (current_tcp_pcb) tcp_recved(current_tcp_pcb, (u16_t)copied);
|
||||
tcp_recv_queue = remainder;
|
||||
network_processing = 0;
|
||||
return (int)copied;
|
||||
}
|
||||
|
||||
int network_tcp_close(void) {
|
||||
if (network_processing) return 0;
|
||||
network_processing = 1;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@ int network_dhcp_acquire(void);
|
|||
int network_get_gateway_ip(ipv4_address_t* ip);
|
||||
int network_get_dns_ip(ipv4_address_t *ip);
|
||||
int network_icmp_single_ping(ipv4_address_t *dest);
|
||||
int network_tcp_connect(const ipv4_address_t *ip, uint16_t port);
|
||||
int network_tcp_send(const void *data, size_t len);
|
||||
int network_tcp_recv(void *buf, size_t max_len);
|
||||
int network_tcp_recv_nb(void *buf, size_t max_len);
|
||||
int network_tcp_close(void);
|
||||
int network_dns_lookup(const char *name, ipv4_address_t *out_ip);
|
||||
int network_set_dns_server(const ipv4_address_t *ip);
|
||||
void network_cleanup(void);
|
||||
void network_force_unlock(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -329,6 +329,72 @@ uint64_t process_schedule(uint64_t current_rsp) {
|
|||
return current_process->rsp;
|
||||
}
|
||||
|
||||
static void process_cleanup_inner(process_t *proc) {
|
||||
if (!proc || proc->pid == 0xFFFFFFFF) return;
|
||||
|
||||
// 1. Cleanup side effects
|
||||
extern Window win_cmd;
|
||||
if (proc->ui_window && (proc->ui_window != &win_cmd)) {
|
||||
wm_remove_window((Window *)proc->ui_window);
|
||||
proc->ui_window = NULL;
|
||||
}
|
||||
|
||||
extern void fat32_close(struct FAT32_FileHandle *fh);
|
||||
for (int i = 0; i < MAX_PROCESS_FDS; i++) {
|
||||
if (proc->fds[i]) {
|
||||
fat32_close(proc->fds[i]);
|
||||
proc->fds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern void cmd_process_finished(void);
|
||||
cmd_process_finished();
|
||||
|
||||
extern void network_cleanup_pcb(void *pcb);
|
||||
// TODO: We need per-process PCB tracking to call this safely
|
||||
// For now, let's NOT call global network_cleanup
|
||||
}
|
||||
|
||||
void process_terminate(process_t *to_delete) {
|
||||
if (!to_delete || to_delete->pid == 0xFFFFFFFF) return;
|
||||
|
||||
uint64_t rflags;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||
|
||||
process_cleanup_inner(to_delete);
|
||||
|
||||
// 2. Find previous process in circular list
|
||||
process_t *prev = to_delete;
|
||||
while (prev->next != to_delete) {
|
||||
prev = prev->next;
|
||||
}
|
||||
|
||||
if (prev == to_delete) {
|
||||
// Only one process (should be kernel), cannot terminate.
|
||||
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Remove current from list
|
||||
prev->next = to_delete->next;
|
||||
|
||||
if (to_delete == current_process) {
|
||||
current_process = to_delete->next;
|
||||
// WARNING: If this was called as a regular function and not via a task switch,
|
||||
// the stack might be in a weird state. But usually we call this via window manager
|
||||
// or other external triggers.
|
||||
}
|
||||
|
||||
// Mark slot as free
|
||||
to_delete->pid = 0xFFFFFFFF;
|
||||
|
||||
if (to_delete->user_stack_alloc) kfree(to_delete->user_stack_alloc);
|
||||
to_delete->user_stack_alloc = NULL;
|
||||
to_delete->kernel_stack_alloc = NULL;
|
||||
|
||||
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||
}
|
||||
|
||||
uint64_t process_terminate_current(void) {
|
||||
uint64_t rflags;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||
|
|
@ -338,26 +404,7 @@ uint64_t process_terminate_current(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 1. Cleanup side effects
|
||||
extern Window win_cmd;
|
||||
if (current_process->ui_window && (current_process->ui_window != &win_cmd)) {
|
||||
wm_remove_window((Window *)current_process->ui_window);
|
||||
current_process->ui_window = NULL;
|
||||
}
|
||||
|
||||
extern void fat32_close(struct FAT32_FileHandle *fh);
|
||||
for (int i = 0; i < MAX_PROCESS_FDS; i++) {
|
||||
if (current_process->fds[i]) {
|
||||
fat32_close(current_process->fds[i]);
|
||||
current_process->fds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern void cmd_process_finished(void);
|
||||
cmd_process_finished();
|
||||
|
||||
extern void network_cleanup(void);
|
||||
network_cleanup();
|
||||
process_cleanup_inner(current_process);
|
||||
|
||||
// 2. Find previous process in circular list
|
||||
process_t *prev = current_process;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str);
|
|||
process_t* process_get_current(void);
|
||||
uint64_t process_schedule(uint64_t current_rsp);
|
||||
uint64_t process_terminate_current(void);
|
||||
void process_terminate(process_t *proc);
|
||||
|
||||
void process_push_gui_event(process_t *proc, gui_event_t *ev);
|
||||
process_t* process_get_by_ui_window(void* win);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,14 @@ static void user_window_resize(Window *win, int w, int h) {
|
|||
}
|
||||
|
||||
|
||||
static uint64_t syscall_handler_inner(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
|
||||
static uint64_t syscall_handler_inner(registers_t *regs) {
|
||||
uint64_t syscall_num = regs->rax;
|
||||
uint64_t arg1 = regs->rdi;
|
||||
uint64_t arg2 = regs->rsi;
|
||||
uint64_t arg3 = regs->rdx;
|
||||
uint64_t arg4 = regs->r10;
|
||||
uint64_t arg5 = regs->r8;
|
||||
|
||||
extern void cmd_write(const char *str);
|
||||
extern void serial_write(const char *str);
|
||||
|
||||
|
|
@ -561,7 +568,7 @@ static uint64_t syscall_handler_inner(uint64_t syscall_num, uint64_t arg1, uint6
|
|||
} else if (cmd == GUI_CMD_GET_EVENT) {
|
||||
Window *win = (Window *)arg2;
|
||||
gui_event_t *ev_out = (gui_event_t *)arg3;
|
||||
if (!win || !ev_out) return 0;
|
||||
if (!ev_out) return 0;
|
||||
if (proc->gui_event_head != proc->gui_event_tail) {
|
||||
*ev_out = proc->gui_events[proc->gui_event_head];
|
||||
proc->gui_event_head = (proc->gui_event_head + 1) % MAX_GUI_EVENTS;
|
||||
|
|
@ -1056,6 +1063,11 @@ static uint64_t syscall_handler_inner(uint64_t syscall_num, uint64_t arg1, uint6
|
|||
extern void cmd_set_raw_mode(bool enabled);
|
||||
cmd_set_raw_mode((bool)arg2);
|
||||
return 0;
|
||||
} else if (cmd == 42) { // SYSTEM_CMD_TCP_RECV_NB
|
||||
void *buf = (void *)arg2;
|
||||
size_t max_len = (size_t)arg3;
|
||||
extern int network_tcp_recv_nb(void *buf, size_t max_len);
|
||||
return (uint64_t)network_tcp_recv_nb(buf, max_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1071,8 +1083,14 @@ uint64_t syscall_handler_c(registers_t *regs) {
|
|||
return process_terminate_current();
|
||||
}
|
||||
|
||||
if (syscall_num == 5 && regs->rdi == 43) { // SYSTEM_CMD_YIELD
|
||||
extern uint64_t process_schedule(uint64_t current_rsp);
|
||||
regs->rax = 0;
|
||||
return process_schedule((uint64_t)regs);
|
||||
}
|
||||
|
||||
// Normal syscalls
|
||||
regs->rax = syscall_handler_inner(regs->rax, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8);
|
||||
regs->rax = syscall_handler_inner(regs);
|
||||
|
||||
// Return current RSP to assembly wrapper
|
||||
return (uint64_t)regs;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,10 @@ int sys_tcp_recv(void *buf, size_t max_len) {
|
|||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_RECV, (uint64_t)buf, (uint64_t)max_len);
|
||||
}
|
||||
|
||||
int sys_tcp_recv_nb(void *buf, size_t max_len) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_RECV_NB, (uint64_t)buf, (uint64_t)max_len);
|
||||
}
|
||||
|
||||
int sys_tcp_close(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_TCP_CLOSE, 0);
|
||||
}
|
||||
|
|
@ -223,3 +227,7 @@ void sys_network_force_unlock(void) {
|
|||
syscall2(SYS_SYSTEM, SYSTEM_CMD_NET_UNLOCK, 0);
|
||||
}
|
||||
|
||||
void sys_yield(void) {
|
||||
syscall1(SYS_SYSTEM, SYSTEM_CMD_YIELD);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@
|
|||
#define SYSTEM_CMD_SET_DNS 38
|
||||
#define SYSTEM_CMD_NET_UNLOCK 39
|
||||
#define SYSTEM_CMD_SET_RAW_MODE 41
|
||||
#define SYSTEM_CMD_TCP_RECV_NB 42
|
||||
#define SYSTEM_CMD_YIELD 43
|
||||
|
||||
// Internal assembly entry into Ring 0
|
||||
extern uint64_t syscall0(uint64_t sys_num);
|
||||
|
|
@ -133,10 +135,12 @@ void sys_set_text_color(uint32_t color);
|
|||
int sys_tcp_connect(const net_ipv4_address_t *ip, uint16_t port);
|
||||
int sys_tcp_send(const void *data, size_t len);
|
||||
int sys_tcp_recv(void *buf, size_t max_len);
|
||||
int sys_tcp_recv_nb(void *buf, size_t max_len);
|
||||
int sys_tcp_close(void);
|
||||
int sys_dns_lookup(const char *name, net_ipv4_address_t *out_ip);
|
||||
int sys_set_dns_server(const net_ipv4_address_t *ip);
|
||||
void sys_network_force_unlock(void);
|
||||
void sys_yield(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (!connected) break;
|
||||
|
||||
int len = sys_tcp_recv(recv_buf, sizeof(recv_buf) - 1);
|
||||
int len = sys_tcp_recv_nb(recv_buf, sizeof(recv_buf) - 1);
|
||||
if (len < 0) {
|
||||
printf("\r\n[Connection error]\r\n");
|
||||
connected = 0;
|
||||
|
|
@ -377,8 +377,7 @@ int main(int argc, char **argv) {
|
|||
connected = 0;
|
||||
break;
|
||||
}
|
||||
// Brief spin
|
||||
for (volatile int d = 0; d < 100; d++);
|
||||
sys_yield();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue