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/tmpfs.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/tmpfs.c')
-rw-r--r-- | kernel/fs/tmpfs.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/kernel/fs/tmpfs.c b/kernel/fs/tmpfs.c new file mode 100644 index 0000000..a9a3c1f --- /dev/null +++ b/kernel/fs/tmpfs.c @@ -0,0 +1,96 @@ +#include <assert.h> +#include <errno.h> +#include <fs/fifo.h> +#include <fs/tmpfs.h> +#include <halts.h> +#include <sched/scheduler.h> +#include <stdint.h> + +void tmp_close(vfs_fd_t *fd) { + fd->inode->is_open = 0; + ((tmp_inode *)fd->inode->internal_object)->read_inode->is_open = 0; +} + +int tmp_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (child_file->is_closed) + return -EPIPE; + + int rc = fifo_object_write(buffer, offset, len, child_file->fifo); + calling_file->read_inode->has_data = child_file->fifo->has_data; + fd->inode->can_write = child_file->fifo->can_write; + return rc; +} + +int tmp_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (calling_file->is_closed) + return -EPIPE; + + int rc = fifo_object_read(buffer, offset, len, calling_file->fifo); + fd->inode->has_data = calling_file->fifo->has_data; + calling_file->read_inode->can_write = child_file->fifo->can_write; + return rc; +} + +void dual_pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, + NULL /*get_vm_object*/, NULL /*truncate*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} + +void pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, + NULL /*get_vm_object*/, NULL/*truncate*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} |