Ver Fonte

feat(fs): add sys_dup3 (#755)

* feat(fs): add sys_dup3
zwb0x00 há 10 meses atrás
pai
commit
40348dd8d5

+ 15 - 0
kernel/src/filesystem/vfs/syscall.rs

@@ -1020,6 +1020,21 @@ impl Syscall {
         return Self::do_dup2(oldfd, newfd, &mut fd_table_guard);
     }
 
+    pub fn dup3(oldfd: i32, newfd: i32, flags: u32) -> Result<usize, SystemError> {
+        let flags = FileMode::from_bits_truncate(flags);
+        if (flags.bits() & !FileMode::O_CLOEXEC.bits()) != 0 {
+            return Err(SystemError::EINVAL);
+        }
+
+        if oldfd == newfd {
+            return Err(SystemError::EINVAL);
+        }
+
+        let binding = ProcessManager::current_pcb().fd_table();
+        let mut fd_table_guard = binding.write();
+        return Self::do_dup3(oldfd, newfd, flags, &mut fd_table_guard);
+    }
+
     fn do_dup2(
         oldfd: i32,
         newfd: i32,

+ 7 - 0
kernel/src/syscall/mod.rs

@@ -399,6 +399,13 @@ impl Syscall {
                 Self::dup2(oldfd, newfd)
             }
 
+            SYS_DUP3 => {
+                let oldfd: i32 = args[0] as c_int;
+                let newfd: i32 = args[1] as c_int;
+                let flags: u32 = args[2] as u32;
+                Self::dup3(oldfd, newfd, flags)
+            }
+
             SYS_SOCKET => Self::socket(args[0], args[1], args[2]),
             SYS_SETSOCKOPT => {
                 let optval = args[3] as *const u8;

+ 1 - 0
user/apps/test_dup3/.gitignore

@@ -0,0 +1 @@
+test_dup3

+ 20 - 0
user/apps/test_dup3/Makefile

@@ -0,0 +1,20 @@
+ifeq ($(ARCH), x86_64)
+	CROSS_COMPILE=x86_64-linux-musl-
+else ifeq ($(ARCH), riscv64)
+	CROSS_COMPILE=riscv64-linux-musl-
+endif
+
+CC=$(CROSS_COMPILE)gcc
+
+.PHONY: all
+all: main.c
+	$(CC) -static -o test_dup3 main.c
+
+.PHONY: install clean
+install: all
+	mv test_dup3 $(DADK_CURRENT_BUILD_DIR)/test_dup3
+
+clean:
+	rm test_dup3 *.o
+
+fmt:

+ 30 - 0
user/apps/test_dup3/main.c

@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main() {
+    int fd = open("/history_commands.txt", O_RDONLY);
+    if (fd < 0) {
+        perror("Failed to open file");
+        return 1;
+    }
+
+    int new_fd = 777;
+    int rt = dup3(fd, new_fd, O_CLOEXEC);
+    if (rt < 0) {
+        perror("Failed to duplicate file descriptor with flags");
+    }
+
+    char buffer[100];
+    int bytes_read = read(new_fd, buffer, sizeof(buffer));
+    if (bytes_read < 0) {
+        perror("Failed to read data");
+        return 1;
+    }
+
+    printf("Data:\n %.*s\n", bytes_read, buffer);
+
+    close(fd);
+    close(new_fd);
+    return 0;
+}

+ 22 - 0
user/dadk/config/test_dup3_0_1_0.dadk

@@ -0,0 +1,22 @@
+{
+  "name": "test_dup3",
+  "version": "0.1.0",
+  "description": "测试dup3",
+  "task_type": {
+    "BuildFromSource": {
+      "Local": {
+        "path": "apps/test_dup3"
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "make install"
+  },
+  "install": {
+    "in_dragonos_path": "/bin"
+  },
+  "clean": {
+    "clean_command": "make clean"
+  }
+}