Convert directory reading to generic stream

Freywar Ulvnaudgari 1 month ago
parent 340bd4edeb
commit cbf21bafdc
  1. 79
      src/kernel/fat16.c
  2. 29
      src/kernel/syscall.c
  3. 1
      src/kernel/syscall.h
  4. 29
      src/user/app/ls/ls.c
  5. 7
      src/user/syscall.asm
  6. 2
      src/user/syscall.h

@ -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) {

@ -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(&current_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:

@ -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

@ -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) {

@ -30,13 +30,6 @@ spawn:
syscall
ret
global readdir
readdir:
mov r10, rcx
mov rax, 5
syscall
ret
global open
open:
mov rax, 6

@ -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);

Loading…
Cancel
Save