strat9_kernel/syscall/
fcntl.rs1use crate::{process::current_task_clone, syscall::error::SyscallError};
6
7pub const F_DUPFD: u64 = 0;
9pub const F_GETFD: u64 = 1;
10pub const F_SETFD: u64 = 2;
11pub const F_GETFL: u64 = 3;
12pub const F_SETFL: u64 = 4;
13
14pub const FD_CLOEXEC: u64 = 1;
16
17pub fn sys_fcntl(fd: u64, cmd: u64, arg: u64) -> Result<u64, SyscallError> {
23 if fd > u32::MAX as u64 {
24 return Err(SyscallError::BadHandle);
25 }
26 let task = current_task_clone().ok_or(SyscallError::PermissionDenied)?;
27
28 match cmd {
29 F_GETFD => {
30 unsafe {
32 let fd_table = &*task.process.fd_table.get();
33 let cloexec = fd_table.get_cloexec(fd as u32)?;
34 Ok(if cloexec { FD_CLOEXEC } else { 0 })
35 }
36 }
37 F_SETFD => {
38 unsafe {
40 let fd_table = &mut *task.process.fd_table.get();
41 let cloexec = (arg & FD_CLOEXEC) != 0;
42 fd_table.set_cloexec(fd as u32, cloexec)?;
43 Ok(0)
44 }
45 }
46 F_DUPFD => {
47 if arg > u32::MAX as u64 {
48 return Err(SyscallError::InvalidArgument);
49 }
50 unsafe {
51 let fd_table = &mut *task.process.fd_table.get();
52 let new_fd = fd_table.duplicate_from(fd as u32, arg as u32)?;
53 Ok(new_fd as u64)
54 }
55 }
56 F_GETFL | F_SETFL => {
57 Err(SyscallError::NotImplemented)
59 }
60 _ => Err(SyscallError::InvalidArgument),
61 }
62}