diff options
author | Anton Kling <anton@kling.gg> | 2023-10-30 22:12:14 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-31 00:18:38 +0100 |
commit | 8a9208612eec8ddae4c418485d848ecfa0613699 (patch) | |
tree | 2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/fs/fifo.c | |
parent | ca76600acc8bf7a02346efa5bd8f17072210ec01 (diff) |
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain
header files and to make the folder structure a bit more clear.
Diffstat (limited to 'kernel/fs/fifo.c')
-rw-r--r-- | kernel/fs/fifo.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/kernel/fs/fifo.c b/kernel/fs/fifo.c new file mode 100644 index 0000000..d515ed7 --- /dev/null +++ b/kernel/fs/fifo.c @@ -0,0 +1,97 @@ +#include "fifo.h" +#include <errno.h> + +#define STARTING_SIZE 4096 + +void fifo_close(vfs_fd_t *fd) { + // TODO: Implement + (void)fd; + return; +} + +int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + file->has_data = 1; + if (file->write_len + len >= file->buffer_len) { + file->can_write = 0; + return -EAGAIN; + } + memcpy(file->buffer + file->write_len, buffer, len); + file->write_len += len; + return len; +} + +int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + if (file->write_len == 0) { + file->has_data = 0; + return -EAGAIN; + } + + if (len == 0) + return 0; + + file->can_write = 1; + if (len > file->write_len) + len = file->write_len; + + memcpy(buffer, file->buffer, len); + // Shift bufffer to the left + memcpy(file->buffer, file->buffer + len, file->buffer_len - len); + + file->write_len -= len; + if (file->write_len == 0) { + file->has_data = 0; + } + return len; +} + +FIFO_FILE *create_fifo_object(void) { + FIFO_FILE *n = kmalloc(sizeof(FIFO_FILE)); + n->buffer = kmalloc(STARTING_SIZE); + n->buffer_len = STARTING_SIZE; + n->write_len = 0; + return n; +} + +int create_fifo(void) { + + int fd_n = 0; + for (; get_current_task()->file_descriptors[fd_n]; fd_n++) + ; + + vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t)); + fd->flags = O_RDWR | O_NONBLOCK; + get_current_task()->file_descriptors[fd_n] = fd; + fd->inode = kmalloc(sizeof(vfs_inode_t)); + + fd->inode->internal_object = (void *)create_fifo_object(); + fd->inode->open = NULL; + fd->inode->read = fifo_read; + fd->inode->write = fifo_write; + fd->inode->close = fifo_close; + fd->inode->get_vm_object = NULL; + fd->inode->is_open = 1; + + return fd_n; +} + +int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + int rc = fifo_object_write(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} + +int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + file->is_blocking = !(fd->flags & O_NONBLOCK); + int rc = fifo_object_read(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} |