Skip to content

Commit 40348dd

Browse files
authored
feat(fs): add sys_dup3 (#755)
* feat(fs): add sys_dup3
1 parent 3b799d1 commit 40348dd

File tree

6 files changed

+95
-0
lines changed

6 files changed

+95
-0
lines changed

kernel/src/filesystem/vfs/syscall.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,21 @@ impl Syscall {
10201020
return Self::do_dup2(oldfd, newfd, &mut fd_table_guard);
10211021
}
10221022

1023+
pub fn dup3(oldfd: i32, newfd: i32, flags: u32) -> Result<usize, SystemError> {
1024+
let flags = FileMode::from_bits_truncate(flags);
1025+
if (flags.bits() & !FileMode::O_CLOEXEC.bits()) != 0 {
1026+
return Err(SystemError::EINVAL);
1027+
}
1028+
1029+
if oldfd == newfd {
1030+
return Err(SystemError::EINVAL);
1031+
}
1032+
1033+
let binding = ProcessManager::current_pcb().fd_table();
1034+
let mut fd_table_guard = binding.write();
1035+
return Self::do_dup3(oldfd, newfd, flags, &mut fd_table_guard);
1036+
}
1037+
10231038
fn do_dup2(
10241039
oldfd: i32,
10251040
newfd: i32,

kernel/src/syscall/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,13 @@ impl Syscall {
399399
Self::dup2(oldfd, newfd)
400400
}
401401

402+
SYS_DUP3 => {
403+
let oldfd: i32 = args[0] as c_int;
404+
let newfd: i32 = args[1] as c_int;
405+
let flags: u32 = args[2] as u32;
406+
Self::dup3(oldfd, newfd, flags)
407+
}
408+
402409
SYS_SOCKET => Self::socket(args[0], args[1], args[2]),
403410
SYS_SETSOCKOPT => {
404411
let optval = args[3] as *const u8;

user/apps/test_dup3/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test_dup3

user/apps/test_dup3/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
ifeq ($(ARCH), x86_64)
2+
CROSS_COMPILE=x86_64-linux-musl-
3+
else ifeq ($(ARCH), riscv64)
4+
CROSS_COMPILE=riscv64-linux-musl-
5+
endif
6+
7+
CC=$(CROSS_COMPILE)gcc
8+
9+
.PHONY: all
10+
all: main.c
11+
$(CC) -static -o test_dup3 main.c
12+
13+
.PHONY: install clean
14+
install: all
15+
mv test_dup3 $(DADK_CURRENT_BUILD_DIR)/test_dup3
16+
17+
clean:
18+
rm test_dup3 *.o
19+
20+
fmt:

user/apps/test_dup3/main.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <fcntl.h>
4+
5+
int main() {
6+
int fd = open("/history_commands.txt", O_RDONLY);
7+
if (fd < 0) {
8+
perror("Failed to open file");
9+
return 1;
10+
}
11+
12+
int new_fd = 777;
13+
int rt = dup3(fd, new_fd, O_CLOEXEC);
14+
if (rt < 0) {
15+
perror("Failed to duplicate file descriptor with flags");
16+
}
17+
18+
char buffer[100];
19+
int bytes_read = read(new_fd, buffer, sizeof(buffer));
20+
if (bytes_read < 0) {
21+
perror("Failed to read data");
22+
return 1;
23+
}
24+
25+
printf("Data:\n %.*s\n", bytes_read, buffer);
26+
27+
close(fd);
28+
close(new_fd);
29+
return 0;
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "test_dup3",
3+
"version": "0.1.0",
4+
"description": "测试dup3",
5+
"task_type": {
6+
"BuildFromSource": {
7+
"Local": {
8+
"path": "apps/test_dup3"
9+
}
10+
}
11+
},
12+
"depends": [],
13+
"build": {
14+
"build_command": "make install"
15+
},
16+
"install": {
17+
"in_dragonos_path": "/bin"
18+
},
19+
"clean": {
20+
"clean_command": "make clean"
21+
}
22+
}

0 commit comments

Comments
 (0)