summaryrefslogtreecommitdiff
path: root/kernel/fs/tmpfs.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 22:12:14 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 00:18:38 +0100
commit8a9208612eec8ddae4c418485d848ecfa0613699 (patch)
tree2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/fs/tmpfs.c
parentca76600acc8bf7a02346efa5bd8f17072210ec01 (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.c96
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;
+}