|
|
|
|
@ -3,6 +3,7 @@ |
|
|
|
|
#include "src/kernel/gdt.h" |
|
|
|
|
#include "src/kernel/path.h" |
|
|
|
|
#include "src/kernel/process.h" |
|
|
|
|
#include "src/kernel/stream.h" |
|
|
|
|
#include "src/kernel/tss.h" |
|
|
|
|
#include "src/lib/layout.h" |
|
|
|
|
#include "src/lib/memory.h" |
|
|
|
|
@ -34,37 +35,17 @@ void syscall_init() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t read(uint64_t fd, uint64_t max, char *to) { |
|
|
|
|
switch (fd) { |
|
|
|
|
case 0: |
|
|
|
|
return current_process->stdin->read(current_process->stdin, max, to); |
|
|
|
|
case 1: |
|
|
|
|
return current_process->stdout->read(current_process->stdout, max, to); |
|
|
|
|
default: |
|
|
|
|
if (!current_process->fds[fd].node) { |
|
|
|
|
if (fd >= MAX_FDS || !current_process->fds[fd]) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
} |
|
|
|
|
if (current_process->fds[fd].offset >= current_process->fds[fd].node->size) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
uint64_t remaining = current_process->fds[fd].node->size - current_process->fds[fd].offset; |
|
|
|
|
uint64_t to_read = remaining > max ? max : remaining; |
|
|
|
|
fs_read(current_process->fds[fd].node, current_process->fds[fd].offset, to_read, to); |
|
|
|
|
current_process->fds[fd].offset += to_read; |
|
|
|
|
return to_read; |
|
|
|
|
} |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
return current_process->fds[fd]->read(current_process->fds[fd], max, to); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t write(uint64_t fd, const char *from, uint64_t bytes) { |
|
|
|
|
switch (fd) { |
|
|
|
|
case 0: |
|
|
|
|
return current_process->stdin->write(current_process->stdin, from, bytes); |
|
|
|
|
case 1: |
|
|
|
|
return current_process->stdout->write(current_process->stdout, from, bytes); |
|
|
|
|
default: |
|
|
|
|
if (fd >= MAX_FDS || !current_process->fds[fd]) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
} |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
return current_process->fds[fd]->write(current_process->fds[fd], from, bytes); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t getcwd(uint64_t max, char *to) { |
|
|
|
|
@ -113,13 +94,13 @@ static uint64_t chdir(const char *path) { |
|
|
|
|
return current_process->cwd->depth; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t spawn(const char *path, uint64_t argc, const char **argv) { |
|
|
|
|
static exit_code_t spawn(const char *path, uint64_t argc, const char **argv) { |
|
|
|
|
fs_node_t *node = path_open_file(current_process->root, current_process->cwd, path); |
|
|
|
|
if (!node) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
return EXIT_CODE_NOT_FOUND; |
|
|
|
|
} |
|
|
|
|
uint8_t *code = memory_allocate(node->size); |
|
|
|
|
fs_read(node, 0, node->size, code); |
|
|
|
|
uint8_t *bin = memory_allocate(node->size); |
|
|
|
|
fs_read(node, 0, node->size, bin); |
|
|
|
|
|
|
|
|
|
uint64_t size = 0; |
|
|
|
|
uint64_t sizes[16]; |
|
|
|
|
@ -133,9 +114,9 @@ static uint64_t spawn(const char *path, uint64_t argc, const char **argv) { |
|
|
|
|
memory_copy(argv[i], sizes[i], blob + offsets[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
process_t *child = process_create(current_process, code, node->size); |
|
|
|
|
process_t *child = process_create(current_process, bin, node->size); |
|
|
|
|
|
|
|
|
|
memory_free(code); |
|
|
|
|
memory_free(bin); |
|
|
|
|
fs_close(node); |
|
|
|
|
|
|
|
|
|
__asm__ volatile("mov %0, %%cr3" : : "r"((uint64_t)VIRT_TO_PHYS((void *)KERNEL_VIRTUAL_PML4)) : "memory"); |
|
|
|
|
@ -163,11 +144,12 @@ static uint64_t spawn(const char *path, uint64_t argc, const char **argv) { |
|
|
|
|
|
|
|
|
|
process_switch_to(&parent->kernel_rsp, child->kernel_rsp, VIRT_TO_PHYS(child->pml4)); |
|
|
|
|
|
|
|
|
|
exit_code_t code = child->code; |
|
|
|
|
tss.rsp0 = (uint64_t)parent->kernel_stack; |
|
|
|
|
current_process = parent; |
|
|
|
|
process_destroy(child); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
return code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t readdir(const char *path, uint64_t index, uint64_t max, char *to) { |
|
|
|
|
@ -199,27 +181,25 @@ static uint64_t open(const char *path) { |
|
|
|
|
if (current_process->free_fd >= MAX_FDS) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
} |
|
|
|
|
fs_node_t *node = path_open_node(current_process->root, current_process->cwd, path); |
|
|
|
|
if (!node) { |
|
|
|
|
stream_t *stream = path_open_stream(current_process->root, current_process->cwd, path); |
|
|
|
|
if (!stream) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
} |
|
|
|
|
current_process->fds[current_process->free_fd].node = node; |
|
|
|
|
current_process->fds[current_process->free_fd].offset++; |
|
|
|
|
current_process->free_fd++; |
|
|
|
|
current_process->fds[current_process->free_fd++] = stream; |
|
|
|
|
return current_process->free_fd - 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t close(uint64_t fd) { |
|
|
|
|
if (fd >= MAX_FDS || !current_process->fds[fd].node) { |
|
|
|
|
if (fd >= MAX_FDS || !current_process->fds[fd]) { |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
} |
|
|
|
|
fs_close(current_process->fds[fd].node); |
|
|
|
|
current_process->fds[fd].node = NUL; |
|
|
|
|
current_process->fds[fd].offset = 0; |
|
|
|
|
current_process->fds[fd]->close(current_process->fds[fd]); |
|
|
|
|
current_process->fds[fd] = NUL; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void exit() { |
|
|
|
|
static void exit(exit_code_t code) { |
|
|
|
|
current_process->code = code; |
|
|
|
|
process_switch_to(¤t_process->kernel_rsp, current_process->parent->kernel_rsp, VIRT_TO_PHYS(current_process->parent->pml4)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -242,7 +222,7 @@ uint64_t syscall_dispatch(uint64_t func, uint64_t arg1, uint64_t arg2, uint64_t |
|
|
|
|
case SYSCALL_CLOSE: |
|
|
|
|
return close(arg1); |
|
|
|
|
case SYSCALL_EXIT: |
|
|
|
|
exit(); |
|
|
|
|
exit(arg1); |
|
|
|
|
return 0; |
|
|
|
|
default: |
|
|
|
|
return (uint64_t)-1; |
|
|
|
|
|