1004e86ffSlogin use core::ffi::{c_char, CStr}; 2004e86ffSlogin 384407d36Slogin use alloc::{boxed::Box, string::ToString}; 4004e86ffSlogin 5004e86ffSlogin use crate::{ 6004e86ffSlogin arch::asm::{current::current_pcb, ptrace::user_mode}, 7*2b771e32SGou Ngai filesystem::vfs::file::FileDescriptorVec, 8004e86ffSlogin include::bindings::bindings::{ 9*2b771e32SGou Ngai pt_regs, verify_area, AT_REMOVEDIR, PAGE_2M_SIZE, PAGE_4K_SIZE, PROC_MAX_FD_NUM, SEEK_CUR, 10*2b771e32SGou Ngai SEEK_END, SEEK_MAX, SEEK_SET, 11004e86ffSlogin }, 12004e86ffSlogin io::SeekFrom, 13*2b771e32SGou Ngai kerror, 14*2b771e32SGou Ngai syscall::SystemError, 15004e86ffSlogin }; 16004e86ffSlogin 17004e86ffSlogin use super::{ 18004e86ffSlogin core::{do_lseek, do_mkdir, do_open, do_read, do_remove_dir, do_unlink_at, do_write}, 19004e86ffSlogin file::{File, FileMode}, 20004e86ffSlogin Dirent, FileType, ROOT_INODE, 21004e86ffSlogin }; 22004e86ffSlogin 23004e86ffSlogin /// @brief 打开文件 24004e86ffSlogin /// 25004e86ffSlogin /// @param regs->r8 path 文件路径 26004e86ffSlogin /// @param regs->r9 o_flags 打开文件的标志位 27004e86ffSlogin /// 28004e86ffSlogin /// @return u64 文件描述符编号,或者是错误码 29004e86ffSlogin #[no_mangle] 30004e86ffSlogin pub extern "C" fn sys_open(regs: &pt_regs) -> u64 { 31004e86ffSlogin let path: &CStr = unsafe { CStr::from_ptr(regs.r8 as usize as *const c_char) }; 32004e86ffSlogin let path: Result<&str, core::str::Utf8Error> = path.to_str(); 33004e86ffSlogin if path.is_err() { 34676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 35004e86ffSlogin } 36004e86ffSlogin let path: &str = path.unwrap(); 37004e86ffSlogin let flags = regs.r9; 38004e86ffSlogin let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32); 39676b8ef6SMork let r: Result<i32, SystemError> = do_open(path, open_flags); 40004e86ffSlogin 41004e86ffSlogin if r.is_ok() { 42004e86ffSlogin return r.unwrap() as u64; 43004e86ffSlogin } else { 44676b8ef6SMork return r.unwrap_err().to_posix_errno() as u64; 45004e86ffSlogin } 46004e86ffSlogin } 47004e86ffSlogin 48004e86ffSlogin /// @brief 关闭文件的系统调用函数 49004e86ffSlogin /// 50004e86ffSlogin /// @param regs->r8 fd:文件描述符编号 51004e86ffSlogin #[no_mangle] 52004e86ffSlogin pub extern "C" fn sys_close(regs: &pt_regs) -> u64 { 53004e86ffSlogin let fd = regs.r8 as i32; 54676b8ef6SMork let r: Result<(), SystemError> = current_pcb().drop_fd(fd); 55004e86ffSlogin 56004e86ffSlogin if r.is_ok() { 57004e86ffSlogin return 0; 58004e86ffSlogin } else { 59676b8ef6SMork return r.unwrap_err().to_posix_errno() as u64; 60004e86ffSlogin } 61004e86ffSlogin } 62004e86ffSlogin 63004e86ffSlogin /// @brief 读取文件的系统调用函数 64004e86ffSlogin /// 65004e86ffSlogin /// @param regs->r8 文件描述符编号 66004e86ffSlogin /// @param regs->r9 输出缓冲区 67004e86ffSlogin /// @param regs->r10 要读取的长度 68004e86ffSlogin #[no_mangle] 69004e86ffSlogin pub extern "C" fn sys_read(regs: &pt_regs) -> u64 { 70004e86ffSlogin let fd = regs.r8 as i32; 71004e86ffSlogin let buf_vaddr = regs.r9 as usize; 72004e86ffSlogin let len = regs.r10 as usize; 73004e86ffSlogin 74004e86ffSlogin // 判断缓冲区是否来自用户态,进行权限校验 75004e86ffSlogin if user_mode(regs) && unsafe { !verify_area(buf_vaddr as u64, len as u64) } { 76004e86ffSlogin // 来自用户态,而buffer在内核态,这样的操作不被允许 77676b8ef6SMork return SystemError::EPERM.to_posix_errno() as u64; 78004e86ffSlogin } 79004e86ffSlogin 80004e86ffSlogin let buf: &mut [u8] = 81004e86ffSlogin unsafe { core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len) }; 82004e86ffSlogin 83676b8ef6SMork let r: Result<usize, SystemError> = do_read(fd, buf); 84004e86ffSlogin 85004e86ffSlogin if r.is_ok() { 86004e86ffSlogin return r.unwrap() as u64; 87004e86ffSlogin } else { 88676b8ef6SMork return r.unwrap_err().to_posix_errno() as u64; 89004e86ffSlogin } 90004e86ffSlogin } 91004e86ffSlogin 92004e86ffSlogin /// @brief 向文件写入数据的系统调用函数 93004e86ffSlogin /// 94004e86ffSlogin /// @param regs->r8 文件描述符编号 95004e86ffSlogin /// @param regs->r9 输入缓冲区 96004e86ffSlogin /// @param regs->r10 要写入的长度 97004e86ffSlogin #[no_mangle] 98004e86ffSlogin pub extern "C" fn sys_write(regs: &pt_regs) -> u64 { 99004e86ffSlogin let fd = regs.r8 as i32; 100004e86ffSlogin let buf_vaddr = regs.r9 as usize; 101004e86ffSlogin let len = regs.r10 as usize; 102004e86ffSlogin 103004e86ffSlogin // 判断缓冲区是否来自用户态,进行权限校验 104004e86ffSlogin if user_mode(regs) && unsafe { !verify_area(buf_vaddr as u64, len as u64) } { 105004e86ffSlogin // 来自用户态,而buffer在内核态,这样的操作不被允许 106676b8ef6SMork return SystemError::EPERM.to_posix_errno() as u64; 107004e86ffSlogin } 108004e86ffSlogin 109004e86ffSlogin let buf: &[u8] = 110004e86ffSlogin unsafe { core::slice::from_raw_parts::<'static, u8>(buf_vaddr as *mut u8, len) }; 111004e86ffSlogin 112676b8ef6SMork let r: Result<usize, SystemError> = do_write(fd, buf); 113004e86ffSlogin 114004e86ffSlogin if r.is_ok() { 115004e86ffSlogin return r.unwrap() as u64; 116004e86ffSlogin } else { 117676b8ef6SMork return r.unwrap_err().to_posix_errno() as u64; 118004e86ffSlogin } 119004e86ffSlogin } 120004e86ffSlogin 121004e86ffSlogin /// @brief 调整文件访问指针位置的系统调用函数 122004e86ffSlogin /// 123004e86ffSlogin /// @param regs->r8 文件描述符编号 124004e86ffSlogin /// @param regs->r9 调整偏移量 125004e86ffSlogin /// @param regs->r10 调整的模式 126004e86ffSlogin #[no_mangle] 127004e86ffSlogin pub extern "C" fn sys_lseek(regs: &pt_regs) -> u64 { 128004e86ffSlogin let fd = regs.r8 as i32; 129004e86ffSlogin let offset = regs.r9 as i64; 130004e86ffSlogin let whence = regs.r10 as u32; 131004e86ffSlogin 132004e86ffSlogin let w: SeekFrom = match whence { 133004e86ffSlogin SEEK_SET => SeekFrom::SeekSet(offset), 134004e86ffSlogin SEEK_CUR => SeekFrom::SeekCurrent(offset), 135004e86ffSlogin SEEK_END => SeekFrom::SeekEnd(offset), 136004e86ffSlogin SEEK_MAX => SeekFrom::SeekEnd(0), 137676b8ef6SMork _ => return SystemError::EINVAL.to_posix_errno() as u64, 138004e86ffSlogin }; 139004e86ffSlogin 140676b8ef6SMork let r: Result<usize, SystemError> = do_lseek(fd, w); 141004e86ffSlogin if r.is_ok() { 142004e86ffSlogin return r.unwrap() as u64; 143004e86ffSlogin } else { 144676b8ef6SMork return r.unwrap_err().to_posix_errno() as u64; 145004e86ffSlogin } 146004e86ffSlogin } 147004e86ffSlogin 148004e86ffSlogin /// @brief 切换工作目录 149004e86ffSlogin /// 150004e86ffSlogin /// @param dest_path 目标路径 151004e86ffSlogin /// 152004e86ffSlogin /// @return 返回码 描述 153004e86ffSlogin /// 0 | 成功 154004e86ffSlogin /// 155004e86ffSlogin /// EACCESS | 权限不足 156004e86ffSlogin /// 157004e86ffSlogin /// ELOOP | 解析path时遇到路径循环 158004e86ffSlogin /// 159004e86ffSlogin /// ENAMETOOLONG | 路径名过长 160004e86ffSlogin /// 161004e86ffSlogin /// ENOENT | 目标文件或目录不存在 162004e86ffSlogin /// 163004e86ffSlogin /// ENODIR | 检索期间发现非目录项 164004e86ffSlogin /// 165004e86ffSlogin /// ENOMEM | 系统内存不足 166004e86ffSlogin /// 167004e86ffSlogin /// EFAULT | 错误的地址 168004e86ffSlogin /// 169004e86ffSlogin /// ENAMETOOLONG | 路径过长 170004e86ffSlogin #[no_mangle] 171004e86ffSlogin pub extern "C" fn sys_chdir(regs: &pt_regs) -> u64 { 172004e86ffSlogin if regs.r8 == 0 { 173676b8ef6SMork return SystemError::EFAULT.to_posix_errno() as u64; 174004e86ffSlogin } 175004e86ffSlogin let ptr = regs.r8 as usize as *const c_char; 176004e86ffSlogin // 权限校验 177004e86ffSlogin if ptr.is_null() 178004e86ffSlogin || (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) }) 179004e86ffSlogin { 180676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 181004e86ffSlogin } 182004e86ffSlogin 183004e86ffSlogin let dest_path: &CStr = unsafe { CStr::from_ptr(ptr) }; 184004e86ffSlogin let dest_path: Result<&str, core::str::Utf8Error> = dest_path.to_str(); 185004e86ffSlogin 186004e86ffSlogin if dest_path.is_err() { 187676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 188004e86ffSlogin } 189004e86ffSlogin 190004e86ffSlogin let dest_path: &str = dest_path.unwrap(); 191004e86ffSlogin 192004e86ffSlogin if dest_path.len() == 0 { 193676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 194004e86ffSlogin } else if dest_path.len() >= PAGE_4K_SIZE as usize { 195676b8ef6SMork return SystemError::ENAMETOOLONG.to_posix_errno() as u64; 196004e86ffSlogin } 197004e86ffSlogin 198004e86ffSlogin let path = Box::new(dest_path.clone()); 199004e86ffSlogin let inode = match ROOT_INODE().lookup(&path) { 200004e86ffSlogin Err(e) => { 201676b8ef6SMork kerror!("Change Directory Failed, Error = {:?}", e); 202676b8ef6SMork return SystemError::ENOENT.to_posix_errno() as u64; 203004e86ffSlogin } 204004e86ffSlogin Ok(i) => i, 205004e86ffSlogin }; 206004e86ffSlogin 207004e86ffSlogin match inode.metadata() { 208004e86ffSlogin Err(e) => { 209676b8ef6SMork kerror!("INode Get MetaData Failed, Error = {:?}", e); 210676b8ef6SMork return SystemError::ENOENT.to_posix_errno() as u64; 211004e86ffSlogin } 212004e86ffSlogin Ok(i) => { 213004e86ffSlogin if let FileType::Dir = i.file_type { 214004e86ffSlogin return 0; 215004e86ffSlogin } else { 216676b8ef6SMork return SystemError::ENOTDIR.to_posix_errno() as u64; 217004e86ffSlogin } 218004e86ffSlogin } 219004e86ffSlogin } 220004e86ffSlogin } 221004e86ffSlogin 222004e86ffSlogin /// @brief 获取目录中的数据 223004e86ffSlogin /// 224004e86ffSlogin /// @param fd 文件描述符号 225004e86ffSlogin /// @return uint64_t dirent的总大小 226004e86ffSlogin #[no_mangle] 227004e86ffSlogin pub extern "C" fn sys_getdents(regs: &pt_regs) -> u64 { 228004e86ffSlogin let fd = regs.r8 as i32; 229004e86ffSlogin let count = regs.r10 as i64; 230004e86ffSlogin let dirent = match unsafe { (regs.r9 as usize as *mut Dirent).as_mut() } { 231004e86ffSlogin None => { 232004e86ffSlogin return 0; 233004e86ffSlogin } 234004e86ffSlogin Some(dirent) => dirent, 235004e86ffSlogin }; 236004e86ffSlogin 237004e86ffSlogin if fd < 0 || fd as u32 > PROC_MAX_FD_NUM { 238676b8ef6SMork return SystemError::EBADF.to_posix_errno() as u64; 239004e86ffSlogin } 240004e86ffSlogin 241004e86ffSlogin if count < 0 { 242676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 243004e86ffSlogin } 244004e86ffSlogin 245004e86ffSlogin // 获取fd 246004e86ffSlogin let file: &mut File = match current_pcb().get_file_mut_by_fd(fd) { 247004e86ffSlogin None => { 248676b8ef6SMork return SystemError::EBADF.to_posix_errno() as u64; 249004e86ffSlogin } 250004e86ffSlogin Some(file) => file, 251004e86ffSlogin }; 252004e86ffSlogin // kdebug!("file={file:?}"); 253004e86ffSlogin 254004e86ffSlogin return match file.readdir(dirent) { 255004e86ffSlogin Err(_) => 0, 256004e86ffSlogin Ok(len) => len, 257004e86ffSlogin }; 258004e86ffSlogin } 259004e86ffSlogin 260004e86ffSlogin /// @brief 创建文件夹 261004e86ffSlogin /// 262004e86ffSlogin /// @param path(r8) 路径 / mode(r9) 模式 263004e86ffSlogin /// 264004e86ffSlogin /// @return uint64_t 负数错误码 / 0表示成功 265004e86ffSlogin #[no_mangle] 266004e86ffSlogin pub extern "C" fn sys_mkdir(regs: &pt_regs) -> u64 { 267004e86ffSlogin let ptr = regs.r8 as usize as *const c_char; 268004e86ffSlogin if ptr.is_null() 269004e86ffSlogin || (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) }) 270004e86ffSlogin { 271676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 272004e86ffSlogin } 273004e86ffSlogin let path: &CStr = unsafe { CStr::from_ptr(ptr) }; 274004e86ffSlogin let path: Result<&str, core::str::Utf8Error> = path.to_str(); 275004e86ffSlogin let mode = regs.r9; 276004e86ffSlogin 277004e86ffSlogin if path.is_err() { 278676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 279004e86ffSlogin } 280004e86ffSlogin 281004e86ffSlogin let path = &path.unwrap().to_string(); 282004e86ffSlogin if path.trim() == "" { 283676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 284004e86ffSlogin } 285004e86ffSlogin 28684407d36Slogin return match do_mkdir(&path.trim(), FileMode::from_bits_truncate(mode as u32)) { 287004e86ffSlogin Err(err) => { 288676b8ef6SMork kerror!("Failed in do_mkdir, Error Code = {:#?}", err); 289676b8ef6SMork err.to_posix_errno() as u64 290004e86ffSlogin } 291004e86ffSlogin Ok(_) => 0, 292004e86ffSlogin }; 293004e86ffSlogin } 294004e86ffSlogin 295004e86ffSlogin ///@brief 删除文件夹、取消文件的链接、删除文件的系统调用 296004e86ffSlogin /// 297004e86ffSlogin ///@param regs->r8 dfd 进程相对路径基准目录的文件描述符(见fcntl.h) 298004e86ffSlogin /// 299004e86ffSlogin ///@param regs->r9 路径名称字符串 300004e86ffSlogin /// 301004e86ffSlogin ///@param regs->r10 flag 预留的标志位,暂时未使用,请置为0。 302004e86ffSlogin /// 303004e86ffSlogin ///@return uint64_t 错误码 304004e86ffSlogin #[no_mangle] 305004e86ffSlogin pub extern "C" fn sys_unlink_at(regs: &pt_regs) -> u64 { 306004e86ffSlogin let _dfd = regs.r8; 307004e86ffSlogin let ptr = regs.r9 as usize as *const c_char; 308004e86ffSlogin if ptr.is_null() 309004e86ffSlogin || (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) }) 310004e86ffSlogin { 311676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 312004e86ffSlogin } 313004e86ffSlogin let path: &CStr = unsafe { CStr::from_ptr(ptr) }; 314004e86ffSlogin let path: Result<&str, core::str::Utf8Error> = path.to_str(); 315004e86ffSlogin let flag = regs.r10; 316004e86ffSlogin if path.is_err() { 317676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 318004e86ffSlogin } 319004e86ffSlogin 320004e86ffSlogin let path = &path.unwrap().to_string(); 321004e86ffSlogin // kdebug!("sys_unlink_at={path:?}"); 322004e86ffSlogin if (flag & (!(AT_REMOVEDIR as u64))) != 0_u64 { 323676b8ef6SMork return SystemError::EINVAL.to_posix_errno() as u64; 324004e86ffSlogin } 325004e86ffSlogin 326004e86ffSlogin if (flag & (AT_REMOVEDIR as u64)) > 0 { 327004e86ffSlogin // kdebug!("rmdir"); 328004e86ffSlogin match do_remove_dir(&path) { 329004e86ffSlogin Err(err) => { 330676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 331676b8ef6SMork return err.to_posix_errno() as u64; 332004e86ffSlogin } 333004e86ffSlogin Ok(_) => { 334004e86ffSlogin return 0; 335004e86ffSlogin } 336004e86ffSlogin } 337004e86ffSlogin } 338004e86ffSlogin 339004e86ffSlogin // kdebug!("rm"); 340004e86ffSlogin match do_unlink_at(&path, FileMode::from_bits_truncate(flag as u32)) { 341004e86ffSlogin Err(err) => { 342676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 343676b8ef6SMork return err.to_posix_errno() as u64; 344004e86ffSlogin } 345004e86ffSlogin Ok(_) => { 346004e86ffSlogin return 0; 347004e86ffSlogin } 348004e86ffSlogin } 349004e86ffSlogin } 350*2b771e32SGou Ngai 351*2b771e32SGou Ngai fn do_dup(oldfd: i32) -> Result<i32, SystemError> { 352*2b771e32SGou Ngai if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) { 353*2b771e32SGou Ngai // 获得当前文件描述符数组 354*2b771e32SGou Ngai // 确认oldfd是否有效 355*2b771e32SGou Ngai if FileDescriptorVec::validate_fd(oldfd) { 356*2b771e32SGou Ngai if let Some(file) = &fds.fds[oldfd as usize] { 357*2b771e32SGou Ngai // 尝试获取对应的文件结构体 358*2b771e32SGou Ngai let file_cp = (file).try_clone(); 359*2b771e32SGou Ngai if file_cp.is_none() { 360*2b771e32SGou Ngai return Err(SystemError::EBADF); 361*2b771e32SGou Ngai } 362*2b771e32SGou Ngai let res = current_pcb().alloc_fd(*file_cp.unwrap(), None); 363*2b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 364*2b771e32SGou Ngai return res; 365*2b771e32SGou Ngai } 366*2b771e32SGou Ngai // oldfd对应的文件不存在 367*2b771e32SGou Ngai return Err(SystemError::EBADF); 368*2b771e32SGou Ngai } 369*2b771e32SGou Ngai return Err(SystemError::EBADF); 370*2b771e32SGou Ngai } else { 371*2b771e32SGou Ngai return Err(SystemError::EMFILE); 372*2b771e32SGou Ngai } 373*2b771e32SGou Ngai } 374*2b771e32SGou Ngai 375*2b771e32SGou Ngai #[no_mangle] 376*2b771e32SGou Ngai /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd 377*2b771e32SGou Ngai pub extern "C" fn sys_dup(regs: &pt_regs) -> u64 { 378*2b771e32SGou Ngai let fd: i32 = regs.r8 as i32; 379*2b771e32SGou Ngai let r = do_dup(fd); 380*2b771e32SGou Ngai if r.is_ok() { 381*2b771e32SGou Ngai return r.unwrap() as u64; 382*2b771e32SGou Ngai } else { 383*2b771e32SGou Ngai return r.unwrap_err().to_posix_errno() as u64; 384*2b771e32SGou Ngai } 385*2b771e32SGou Ngai } 386*2b771e32SGou Ngai 387*2b771e32SGou Ngai fn do_dup2(oldfd: i32, newfd: i32) -> Result<i32, SystemError> { 388*2b771e32SGou Ngai if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) { 389*2b771e32SGou Ngai // 获得当前文件描述符数组 390*2b771e32SGou Ngai if FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd) { 391*2b771e32SGou Ngai //确认oldfd, newid是否有效 392*2b771e32SGou Ngai if oldfd == newfd { 393*2b771e32SGou Ngai // 若oldfd与newfd相等 394*2b771e32SGou Ngai return Ok(newfd); 395*2b771e32SGou Ngai } 396*2b771e32SGou Ngai 397*2b771e32SGou Ngai if let Some(file) = &fds.fds[oldfd as usize] { 398*2b771e32SGou Ngai if fds.fds[newfd as usize].is_some() { 399*2b771e32SGou Ngai // close newfd 400*2b771e32SGou Ngai if let Err(_) = current_pcb().drop_fd(newfd) { 401*2b771e32SGou Ngai // An I/O error occurred while attempting to close fildes2. 402*2b771e32SGou Ngai return Err(SystemError::EIO); 403*2b771e32SGou Ngai } 404*2b771e32SGou Ngai } 405*2b771e32SGou Ngai 406*2b771e32SGou Ngai // 尝试获取对应的文件结构体 407*2b771e32SGou Ngai let file_cp = file.try_clone(); 408*2b771e32SGou Ngai if file_cp.is_none() { 409*2b771e32SGou Ngai return Err(SystemError::EBADF); 410*2b771e32SGou Ngai } 411*2b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 412*2b771e32SGou Ngai let res = current_pcb().alloc_fd(*file_cp.unwrap(), Some(newfd)); 413*2b771e32SGou Ngai 414*2b771e32SGou Ngai return res; 415*2b771e32SGou Ngai } 416*2b771e32SGou Ngai return Err(SystemError::EBADF); 417*2b771e32SGou Ngai } else { 418*2b771e32SGou Ngai return Err(SystemError::EBADF); 419*2b771e32SGou Ngai } 420*2b771e32SGou Ngai } 421*2b771e32SGou Ngai // 从pcb获取文件描述符数组失败 422*2b771e32SGou Ngai return Err(SystemError::EMFILE); 423*2b771e32SGou Ngai } 424*2b771e32SGou Ngai 425*2b771e32SGou Ngai #[no_mangle] 426*2b771e32SGou Ngai /// @brief 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体, 427*2b771e32SGou Ngai /// 并返回新复制的文件结构体对应的fd 428*2b771e32SGou Ngai pub extern "C" fn sys_dup2(regs: &pt_regs) -> u64 { 429*2b771e32SGou Ngai let ofd = regs.r8 as i32; 430*2b771e32SGou Ngai let nfd = regs.r9 as i32; 431*2b771e32SGou Ngai let r = do_dup2(ofd, nfd); 432*2b771e32SGou Ngai if r.is_ok() { 433*2b771e32SGou Ngai return r.unwrap() as u64; 434*2b771e32SGou Ngai } else { 435*2b771e32SGou Ngai return r.unwrap_err().to_posix_errno() as u64; 436*2b771e32SGou Ngai } 437*2b771e32SGou Ngai } 438