diff --git a/src/kernel/fat16.c b/src/kernel/fat16.c index e53c4b5..23d816e 100644 --- a/src/kernel/fat16.c +++ b/src/kernel/fat16.c @@ -205,39 +205,80 @@ typedef struct { stream_t stream; fs_node_t *node; uint64_t offset; -} fat16_stream_t; +} fat16_file_stream_t; -static uint64_t stream_write(__attribute__((unused)) const stream_t *self, __attribute__((unused)) const char *from, - __attribute__((unused)) uint64_t bytes) { +static uint64_t file_stream_write(__attribute__((unused)) const stream_t *self, __attribute__((unused)) const char *from, + __attribute__((unused)) uint64_t bytes) { return (uint64_t)-1; } -static uint64_t stream_read(const stream_t *self, uint64_t max, char *to) { - fat16_stream_t *fss = (fat16_stream_t *)self; - if (fss->offset >= fss->node->size) { +static uint64_t file_stream_read(const stream_t *self, uint64_t max, char *to) { + fat16_file_stream_t *ffs = (fat16_file_stream_t *)self; + if (ffs->offset >= ffs->node->size) { return 0; } - uint64_t remaining = fss->node->size - fss->offset; + uint64_t remaining = ffs->node->size - ffs->offset; uint64_t to_read = remaining > max ? max : remaining; - fat16_read(fss->node, fss->offset, to_read, to); - fss->offset += to_read; + fat16_read(ffs->node, ffs->offset, to_read, to); + ffs->offset += to_read; return to_read; } -static void stream_close(stream_t *self) { - fat16_stream_t *fss = (fat16_stream_t *)self; - fat16_close(fss->node); +static void file_stream_close(stream_t *self) { + fat16_file_stream_t *ffs = (fat16_file_stream_t *)self; + fat16_close(ffs->node); + memory_free(self); +} + +typedef struct { + stream_t stream; + fs_node_t *node; + uint64_t index; +} fat16_directory_stream_t; + +static uint64_t directory_stream_write(__attribute__((unused)) const stream_t *self, __attribute__((unused)) const char *from, + __attribute__((unused)) uint64_t bytes) { + return (uint64_t)-1; +} + +static uint64_t directory_stream_read(const stream_t *self, uint64_t max, char *to) { + fat16_directory_stream_t *fds = (fat16_directory_stream_t *)self; + fs_node_t *node = fat16_open_at(fds->node, fds->index++); + if (!node) { + return 0; + } + uint64_t length = string_length(node->name); + uint64_t to_read = length + 1 > max ? max : length + 1; + memory_copy(node->name, to_read, to); + to[max - 1] = '\0'; + + return to_read; +} + +static void directory_stream_close(stream_t *self) { + fat16_directory_stream_t *fds = (fat16_directory_stream_t *)self; + fat16_close(fds->node); memory_free(self); } stream_t *fat16_open_stream(const fs_node_t *source) { - fat16_stream_t *result = memory_allocate(sizeof(fat16_node_t)); - result->stream.read = stream_read; - result->stream.write = stream_write; - result->stream.close = stream_close; - result->node = fat16_open_again(source); - result->offset = 0; - return (stream_t *)result; + if (!source->is_dir) { + fat16_file_stream_t *result = memory_allocate(sizeof(fat16_file_stream_t)); + result->stream.read = file_stream_read; + result->stream.write = file_stream_write; + result->stream.close = file_stream_close; + result->node = fat16_open_again(source); + result->offset = 0; + return (stream_t *)result; + } else { + fat16_directory_stream_t *result = memory_allocate(sizeof(fat16_directory_stream_t)); + result->stream.read = directory_stream_read; + result->stream.write = directory_stream_write; + result->stream.close = directory_stream_close; + result->node = fat16_open_again(source); + result->index = 0; + return (stream_t *)result; + } } void fat16_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to) { diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index f138c2f..0fcf3b7 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -152,31 +152,6 @@ static exit_code_t spawn(const char *path, uint64_t argc, const char **argv) { return code; } -static uint64_t readdir(const char *path, uint64_t index, uint64_t max, char *to) { - fs_node_t *dir = path_open_directory(current_process->root, current_process->cwd, path); - if (!dir) { - return (uint64_t)-1; - } - fs_node_t *item = fs_open_at(dir, index); - if (!item) { - if (dir != current_process->root) { - fs_close(dir); - } - return 0; - } - uint64_t length = string_length(item->name); - uint64_t size = length > max - 1 ? max - 1 : length; - memory_copy(item->name, size, to); - to[size] = '\0'; - - fs_close(item); - if (dir != current_process->root) { - fs_close(dir); - } - - return size; -} - static uint64_t open(const char *path) { if (current_process->free_fd >= MAX_FDS) { return (uint64_t)-1; @@ -203,7 +178,7 @@ static void exit(exit_code_t code) { process_switch_to(¤t_process->kernel_rsp, current_process->parent->kernel_rsp, VIRT_TO_PHYS(current_process->parent->pml4)); } -uint64_t syscall_dispatch(uint64_t func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) { +uint64_t syscall_dispatch(uint64_t func, uint64_t arg1, uint64_t arg2, uint64_t arg3, __attribute__((unused)) uint64_t arg4) { switch (func) { case SYSCALL_READ: return read(arg1, arg2, (char *)arg3); @@ -215,8 +190,6 @@ uint64_t syscall_dispatch(uint64_t func, uint64_t arg1, uint64_t arg2, uint64_t return chdir((const char *)arg1); case SYSCALL_SPAWN: return spawn((const char *)arg1, arg2, (const char **)arg3); - case SYSCALL_READDIR: - return readdir((const char *)arg1, arg2, arg3, (char *)arg4); case SYSCALL_OPEN: return open((const char *)arg1); case SYSCALL_CLOSE: diff --git a/src/kernel/syscall.h b/src/kernel/syscall.h index 0848c65..9d95467 100644 --- a/src/kernel/syscall.h +++ b/src/kernel/syscall.h @@ -7,7 +7,6 @@ #define SYSCALL_GETCWD 2 #define SYSCALL_CHDIR 3 #define SYSCALL_SPAWN 4 -#define SYSCALL_READDIR 5 #define SYSCALL_OPEN 6 #define SYSCALL_CLOSE 7 #define SYSCALL_EXIT 60 diff --git a/src/user/app/ls/ls.c b/src/user/app/ls/ls.c index 22ec67d..19a0b22 100644 --- a/src/user/app/ls/ls.c +++ b/src/user/app/ls/ls.c @@ -6,21 +6,28 @@ #define PRINT_D(s) write(1, s, string_length(s)); exit_code_t ls(const char *path) { - uint64_t i = 0; - while (1) { - char out[100]; - uint64_t s = readdir(path, i, 100, out); - if (!s) { - return EXIT_CODE_OK; - } - if (s == (uint64_t)-1) { - PRINT_S("ls: path does not exist\n"); + uint64_t fd = open(path); + + if (fd == (uint64_t)-1) { + PRINT_S("ls: path does not exist\n"); + return EXIT_CODE_GENERAL_FAILURE; + } + + char buffer[100]; + uint64_t bytes; + while ((bytes = read(fd, 100, buffer))) { + if (bytes == (uint64_t)-1) { + PRINT_S("ls: could not read directory\n"); + close(fd); return EXIT_CODE_GENERAL_FAILURE; } - PRINT_D(out); + write(1, buffer, bytes - 1); PRINT_S("\n"); - i++; } + + close(fd); + + return 0; } exit_code_t main(uint64_t argc, const char **argv) { diff --git a/src/user/syscall.asm b/src/user/syscall.asm index 16b0d71..d68b02e 100644 --- a/src/user/syscall.asm +++ b/src/user/syscall.asm @@ -30,13 +30,6 @@ spawn: syscall ret -global readdir -readdir: - mov r10, rcx - mov rax, 5 - syscall - ret - global open open: mov rax, 6 diff --git a/src/user/syscall.h b/src/user/syscall.h index d2878b1..5124d32 100644 --- a/src/user/syscall.h +++ b/src/user/syscall.h @@ -13,8 +13,6 @@ uint64_t chdir(const char *path); exit_code_t spawn(const char *path, uint64_t argc, const char **argv); -uint64_t readdir(const char *path, uint64_t index, uint64_t max, char *to); - uint64_t open(const char *path); uint64_t close(uint64_t fd);