Browse Source

feat(syscall): add fcntl64

greatbridf 1 năm trước cách đây
mục cha
commit
09fa92b097

+ 15 - 7
gblibc/include/fcntl.h

@@ -3,13 +3,21 @@
 
 #include <stdint.h>
 
-#define O_CREAT (1 << 0)
-#define O_RDONLY (1 << 1)
-#define O_WRONLY (1 << 2)
-#define O_RDWR (1 << 3)
-#define O_DIRECTORY (1 << 4)
-#define O_APPEND (1 << 5)
-#define O_TRUNC (1 << 6)
+#define O_RDONLY          00
+#define O_WRONLY          01
+#define O_RDWR            02
+#define O_CREAT         0100
+#define O_TRUNC        01000
+#define O_APPEND       02000
+#define O_DIRECTORY  0200000
+#define O_CLOEXEC   02000000
+
+#define F_DUPFD 0
+#define F_GETFD 1
+#define F_SETFD 2
+// TODO: more flags
+
+#define FD_CLOEXEC 1
 
 #define AT_FDCWD (-100)
 

+ 10 - 0
include/kernel/process.hpp

@@ -210,6 +210,7 @@ public:
             {
                 .read = 1,
                 .write = 0,
+                .close_on_exec = 0,
             },
         });
 
@@ -230,6 +231,7 @@ public:
             {
                 .read = 0,
                 .write = 1,
+                .close_on_exec = 0,
             },
         });
         fd = next_fd();
@@ -255,6 +257,14 @@ public:
         arr.erase(iter);
     }
 
+    constexpr void onexec()
+    {
+        for (auto [ fd, file ] : arr) {
+            if (file->flags.close_on_exec)
+                close(fd);
+        }
+    }
+
     constexpr void close_all(void)
     {
         for (auto&& [ fd, file ] : arr) {

+ 7 - 6
include/kernel/vfs.hpp

@@ -251,18 +251,19 @@ struct file {
         ind,
         pipe,
         socket,
-    } type;
+    } type {};
     union {
         inode* ind;
         pipe* pp;
-    } ptr;
-    vfs::dentry* parent;
-    size_t cursor;
-    size_t ref;
+    } ptr {};
+    vfs::dentry* parent {};
+    size_t cursor {};
+    size_t ref {};
     struct file_flags {
         uint32_t read : 1;
         uint32_t write : 1;
-    } flags;
+        uint32_t close_on_exec : 1;
+    } flags {};
 };
 
 inline fs::vfs::dentry* fs_root;

+ 2 - 1
src/kernel/process.cpp

@@ -114,8 +114,9 @@ int filearr::open(const process &current, const char *filename, uint32_t flags)
         0,
         1,
         {
-            .read = !!(flags & (O_RDONLY | O_RDWR)),
+            .read = !(flags & O_WRONLY),
             .write = !!(flags & (O_WRONLY | O_RDWR)),
+            .close_on_exec = !!(flags & O_CLOEXEC),
         },
     });
 

+ 23 - 0
src/kernel/syscall.cpp

@@ -199,6 +199,8 @@ int _syscall_execve(interrupt_stack* data)
     if (!d.exec_dent)
         return -ENOENT;
 
+    current_process->files.onexec();
+
     int ret = types::elf::elf32_load(&d);
     if (ret != GB_OK)
         return -d.errcode;
@@ -706,6 +708,26 @@ int _syscall_statx(interrupt_stack* data)
     return ret;
 }
 
+int _syscall_fcntl64(interrupt_stack* data)
+{
+    SYSCALL_ARG1(int, fd);
+    SYSCALL_ARG2(int, cmd);
+    SYSCALL_ARG3(unsigned long, arg);
+
+    auto* file = current_process->files[fd];
+    if (!file)
+        return -EBADF;
+
+    switch (cmd) {
+    case F_SETFD:
+        file->flags.close_on_exec = !!(arg & FD_CLOEXEC);
+        return 0;
+    default:
+        not_implemented();
+        return -EINVAL;
+    }
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = SYSCALL_NO;
@@ -757,6 +779,7 @@ void init_syscall(void)
     syscall_handlers[0xb7] = _syscall_getcwd;
     syscall_handlers[0xc0] = _syscall_mmap_pgoff;
     syscall_handlers[0xc7] = _syscall_getuid;
+    syscall_handlers[0xdd] = _syscall_fcntl64;
     syscall_handlers[0xef] = _syscall_sendfile64;
     syscall_handlers[0xf3] = _syscall_set_thread_area;
     syscall_handlers[0xfc] = _syscall_exit; // we implement exit_group as exit for now