From c6b53345d9b1a5ea66c4060236cfa3468480676c Mon Sep 17 00:00:00 2001 From: zwb0x00 Date: Tue, 23 Apr 2024 02:07:09 +0800 Subject: [PATCH] impl sys_dup3 --- kernel/src/filesystem/vfs/syscall.rs | 10 +++++++++ kernel/src/syscall/mod.rs | 8 +++++++ user/apps/test_dup3/.gitignore | 1 + user/apps/test_dup3/Makefile | 20 ++++++++++++++++++ user/apps/test_dup3/main.c | 30 +++++++++++++++++++++++++++ user/dadk/config/test_dup3_0_1_0.dadk | 22 ++++++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 user/apps/test_dup3/.gitignore create mode 100644 user/apps/test_dup3/Makefile create mode 100644 user/apps/test_dup3/main.c create mode 100644 user/dadk/config/test_dup3_0_1_0.dadk diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index bd885b848..84f919e0d 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -1020,6 +1020,16 @@ impl Syscall { return Self::do_dup2(oldfd, newfd, &mut fd_table_guard); } + pub fn dup3(oldfd: i32, newfd: i32, flags: u32) -> Result { + let flags: FileMode = FileMode::from_bits(flags).ok_or(SystemError::EINVAL)?; + if flags != FileMode::O_CLOEXEC { + 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, diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3f54948f9..3facf064e 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -400,6 +400,14 @@ impl Syscall { Self::dup2(oldfd, newfd) } + #[cfg(target_arch = "x86_64")] + 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; diff --git a/user/apps/test_dup3/.gitignore b/user/apps/test_dup3/.gitignore new file mode 100644 index 000000000..48efb3b1d --- /dev/null +++ b/user/apps/test_dup3/.gitignore @@ -0,0 +1 @@ +test_dup3 \ No newline at end of file diff --git a/user/apps/test_dup3/Makefile b/user/apps/test_dup3/Makefile new file mode 100644 index 000000000..5d1338192 --- /dev/null +++ b/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: \ No newline at end of file diff --git a/user/apps/test_dup3/main.c b/user/apps/test_dup3/main.c new file mode 100644 index 000000000..0a974b1ca --- /dev/null +++ b/user/apps/test_dup3/main.c @@ -0,0 +1,30 @@ +#include +#include +#include + +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; +} diff --git a/user/dadk/config/test_dup3_0_1_0.dadk b/user/dadk/config/test_dup3_0_1_0.dadk new file mode 100644 index 000000000..d452b0e91 --- /dev/null +++ b/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" + } +}