From 02194a2557b50bf850ff2a26d6e1eb6e7b67bb7c Mon Sep 17 00:00:00 2001
From: Anton Kling <anton@kling.gg>
Date: Sat, 23 Nov 2024 15:00:16 +0100
Subject: vfs: Add O_APPEND support + refactoring

---
 kernel/fs/vfs.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

(limited to 'kernel/fs/vfs.c')

diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c
index 1f28f13..25e2423 100644
--- a/kernel/fs/vfs.c
+++ b/kernel/fs/vfs.c
@@ -382,6 +382,50 @@ int vfs_pwrite(int fd, void *buf, u64 count, u64 offset) {
   return rc;
 }
 
+// FIXME: These should be in a shared header file with libc
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+int vfs_lseek(int fd, int offset, int whence) {
+  vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL);
+  if (!fd_ptr) {
+    return -EBADF;
+  }
+
+  off_t ret_offset = fd_ptr->offset;
+  switch (whence) {
+  case SEEK_SET:
+    ret_offset = offset;
+    break;
+  case SEEK_CUR:
+    ret_offset += offset;
+    break;
+  case SEEK_END:
+    assert(fd_ptr->inode);
+    ret_offset = fd_ptr->inode->file_size + offset;
+    break;
+  default:
+    return -EINVAL;
+    break;
+  }
+  fd_ptr->offset = ret_offset;
+  return ret_offset;
+}
+
+int vfs_write(int fd, const char *buf, u64 count) {
+  vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL);
+  if (!fd_ptr) {
+    return -EBADF;
+  }
+  if (fd_ptr->mode & O_APPEND) {
+    vfs_lseek(fd, 0, SEEK_END);
+  }
+  int rc = vfs_pwrite(fd, (char *)buf, count, fd_ptr->offset);
+  fd_ptr->offset += rc;
+  return rc;
+}
+
 vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) {
   vfs_fd_t *vfs_fd = get_vfs_fd(fd, NULL);
   if (!vfs_fd) {
-- 
cgit v1.2.3