12dbef785SGnoCiYeH use core::ffi::CStr; 22dbef785SGnoCiYeH 31496ba7bSLoGin use alloc::{ 41496ba7bSLoGin string::{String, ToString}, 51496ba7bSLoGin sync::Arc, 61496ba7bSLoGin vec::Vec, 71496ba7bSLoGin }; 891e9d4abSLoGin use system_error::SystemError; 9004e86ffSlogin 10004e86ffSlogin use crate::{ 11c566df45SLoGin driver::base::{block::SeekFrom, device::device_number::DeviceNumber}, 122b771e32SGou Ngai filesystem::vfs::file::FileDescriptorVec, 132b771e32SGou Ngai kerror, 141496ba7bSLoGin libs::rwlock::RwLockWriteGuard, 154fda81ceSLoGin mm::{verify_area, VirtAddr}, 161496ba7bSLoGin process::ProcessManager, 17709498caSLoGin syscall::{ 18709498caSLoGin user_access::{check_and_clone_cstr, UserBufferReader, UserBufferWriter}, 1991e9d4abSLoGin Syscall, 20709498caSLoGin }, 2167b48188Shoumkh time::TimeSpec, 22004e86ffSlogin }; 23004e86ffSlogin 24004e86ffSlogin use super::{ 25ab5c8ca4Slogin core::{do_mkdir, do_remove_dir, do_unlink_at}, 26709498caSLoGin fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC}, 27004e86ffSlogin file::{File, FileMode}, 280fb515b0SLoGin open::{do_faccessat, do_fchmodat, do_sys_open}, 299b0abe6dSLoGin utils::{rsplit_path, user_path_at}, 30a03c4f9dSLoGin Dirent, FileType, IndexNode, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES, 31004e86ffSlogin }; 3240314b30SXiaoye Zheng // use crate::kdebug; 33004e86ffSlogin 34ab5c8ca4Slogin pub const SEEK_SET: u32 = 0; 35ab5c8ca4Slogin pub const SEEK_CUR: u32 = 1; 36ab5c8ca4Slogin pub const SEEK_END: u32 = 2; 37ab5c8ca4Slogin pub const SEEK_MAX: u32 = 3; 38004e86ffSlogin 3967b48188Shoumkh bitflags! { 4067b48188Shoumkh /// 文件类型和权限 416b4e7a29SLoGin #[repr(C)] 4267b48188Shoumkh pub struct ModeType: u32 { 4367b48188Shoumkh /// 掩码 4467b48188Shoumkh const S_IFMT = 0o0_170_000; 4567b48188Shoumkh /// 文件类型 4667b48188Shoumkh const S_IFSOCK = 0o140000; 4767b48188Shoumkh const S_IFLNK = 0o120000; 4867b48188Shoumkh const S_IFREG = 0o100000; 4967b48188Shoumkh const S_IFBLK = 0o060000; 5067b48188Shoumkh const S_IFDIR = 0o040000; 5167b48188Shoumkh const S_IFCHR = 0o020000; 5267b48188Shoumkh const S_IFIFO = 0o010000; 5367b48188Shoumkh 5467b48188Shoumkh const S_ISUID = 0o004000; 5567b48188Shoumkh const S_ISGID = 0o002000; 5667b48188Shoumkh const S_ISVTX = 0o001000; 5767b48188Shoumkh /// 文件用户权限 5867b48188Shoumkh const S_IRWXU = 0o0700; 5967b48188Shoumkh const S_IRUSR = 0o0400; 6067b48188Shoumkh const S_IWUSR = 0o0200; 6167b48188Shoumkh const S_IXUSR = 0o0100; 6267b48188Shoumkh /// 文件组权限 6367b48188Shoumkh const S_IRWXG = 0o0070; 6467b48188Shoumkh const S_IRGRP = 0o0040; 6567b48188Shoumkh const S_IWGRP = 0o0020; 6667b48188Shoumkh const S_IXGRP = 0o0010; 6767b48188Shoumkh /// 文件其他用户权限 6867b48188Shoumkh const S_IRWXO = 0o0007; 6967b48188Shoumkh const S_IROTH = 0o0004; 7067b48188Shoumkh const S_IWOTH = 0o0002; 7167b48188Shoumkh const S_IXOTH = 0o0001; 7206d5e247SLoGin 7306d5e247SLoGin /// 0o777 7406d5e247SLoGin const S_IRWXUGO = Self::S_IRWXU.bits | Self::S_IRWXG.bits | Self::S_IRWXO.bits; 7506d5e247SLoGin /// 0o7777 7606d5e247SLoGin const S_IALLUGO = Self::S_ISUID.bits | Self::S_ISGID.bits | Self::S_ISVTX.bits| Self::S_IRWXUGO.bits; 7706d5e247SLoGin /// 0o444 7806d5e247SLoGin const S_IRUGO = Self::S_IRUSR.bits | Self::S_IRGRP.bits | Self::S_IROTH.bits; 7906d5e247SLoGin /// 0o222 8006d5e247SLoGin const S_IWUGO = Self::S_IWUSR.bits | Self::S_IWGRP.bits | Self::S_IWOTH.bits; 8106d5e247SLoGin /// 0o111 8206d5e247SLoGin const S_IXUGO = Self::S_IXUSR.bits | Self::S_IXGRP.bits | Self::S_IXOTH.bits; 8306d5e247SLoGin 8406d5e247SLoGin 8567b48188Shoumkh } 8667b48188Shoumkh } 8767b48188Shoumkh 8867b48188Shoumkh #[repr(C)] 8967b48188Shoumkh /// # 文件信息结构体 9067b48188Shoumkh pub struct PosixKstat { 9167b48188Shoumkh /// 硬件设备ID 9267b48188Shoumkh dev_id: u64, 9367b48188Shoumkh /// inode号 9467b48188Shoumkh inode: u64, 9567b48188Shoumkh /// 硬链接数 9667b48188Shoumkh nlink: u64, 9767b48188Shoumkh /// 文件权限 9867b48188Shoumkh mode: ModeType, 9967b48188Shoumkh /// 所有者用户ID 10067b48188Shoumkh uid: i32, 10167b48188Shoumkh /// 所有者组ID 10267b48188Shoumkh gid: i32, 10367b48188Shoumkh /// 设备ID 10467b48188Shoumkh rdev: i64, 10567b48188Shoumkh /// 文件大小 10667b48188Shoumkh size: i64, 10767b48188Shoumkh /// 文件系统块大小 10867b48188Shoumkh blcok_size: i64, 10967b48188Shoumkh /// 分配的512B块数 11067b48188Shoumkh blocks: u64, 11167b48188Shoumkh /// 最后访问时间 11267b48188Shoumkh atime: TimeSpec, 11367b48188Shoumkh /// 最后修改时间 11467b48188Shoumkh mtime: TimeSpec, 11567b48188Shoumkh /// 最后状态变化时间 11667b48188Shoumkh ctime: TimeSpec, 11767b48188Shoumkh /// 用于填充结构体大小的空白数据 11867b48188Shoumkh pub _pad: [i8; 24], 11967b48188Shoumkh } 12067b48188Shoumkh impl PosixKstat { 12167b48188Shoumkh fn new() -> Self { 12267b48188Shoumkh Self { 12367b48188Shoumkh inode: 0, 12467b48188Shoumkh dev_id: 0, 12567b48188Shoumkh mode: ModeType { bits: 0 }, 12667b48188Shoumkh nlink: 0, 12767b48188Shoumkh uid: 0, 12867b48188Shoumkh gid: 0, 12967b48188Shoumkh rdev: 0, 13067b48188Shoumkh size: 0, 13167b48188Shoumkh atime: TimeSpec { 13267b48188Shoumkh tv_sec: 0, 13367b48188Shoumkh tv_nsec: 0, 13467b48188Shoumkh }, 13567b48188Shoumkh mtime: TimeSpec { 13667b48188Shoumkh tv_sec: 0, 13767b48188Shoumkh tv_nsec: 0, 13867b48188Shoumkh }, 13967b48188Shoumkh ctime: TimeSpec { 14067b48188Shoumkh tv_sec: 0, 14167b48188Shoumkh tv_nsec: 0, 14267b48188Shoumkh }, 14367b48188Shoumkh blcok_size: 0, 14467b48188Shoumkh blocks: 0, 14567b48188Shoumkh _pad: Default::default(), 14667b48188Shoumkh } 14767b48188Shoumkh } 14867b48188Shoumkh } 1490fb515b0SLoGin 1500fb515b0SLoGin /// 1510fb515b0SLoGin /// Arguments for how openat2(2) should open the target path. If only @flags and 1520fb515b0SLoGin /// @mode are non-zero, then openat2(2) operates very similarly to openat(2). 1530fb515b0SLoGin /// 1540fb515b0SLoGin /// However, unlike openat(2), unknown or invalid bits in @flags result in 1550fb515b0SLoGin /// -EINVAL rather than being silently ignored. @mode must be zero unless one of 1560fb515b0SLoGin /// {O_CREAT, O_TMPFILE} are set. 1570fb515b0SLoGin /// 1580fb515b0SLoGin /// ## 成员变量 1590fb515b0SLoGin /// 1600fb515b0SLoGin /// - flags: O_* flags. 1610fb515b0SLoGin /// - mode: O_CREAT/O_TMPFILE file mode. 1620fb515b0SLoGin /// - resolve: RESOLVE_* flags. 1630fb515b0SLoGin #[derive(Debug, Clone, Copy)] 1640fb515b0SLoGin #[repr(C)] 1650fb515b0SLoGin pub struct PosixOpenHow { 1660fb515b0SLoGin pub flags: u64, 1670fb515b0SLoGin pub mode: u64, 1680fb515b0SLoGin pub resolve: u64, 1690fb515b0SLoGin } 1700fb515b0SLoGin 1710fb515b0SLoGin impl PosixOpenHow { 1720fb515b0SLoGin #[allow(dead_code)] 1730fb515b0SLoGin pub fn new(flags: u64, mode: u64, resolve: u64) -> Self { 1740fb515b0SLoGin Self { 1750fb515b0SLoGin flags, 1760fb515b0SLoGin mode, 1770fb515b0SLoGin resolve, 1780fb515b0SLoGin } 1790fb515b0SLoGin } 1800fb515b0SLoGin } 1810fb515b0SLoGin 1820fb515b0SLoGin #[derive(Debug, Clone, Copy)] 1830fb515b0SLoGin pub struct OpenHow { 1840fb515b0SLoGin pub o_flags: FileMode, 1850fb515b0SLoGin pub mode: ModeType, 1860fb515b0SLoGin pub resolve: OpenHowResolve, 1870fb515b0SLoGin } 1880fb515b0SLoGin 1890fb515b0SLoGin impl OpenHow { 1900fb515b0SLoGin pub fn new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self { 1910fb515b0SLoGin if !o_flags.contains(FileMode::O_CREAT) { 1920fb515b0SLoGin mode = ModeType::empty(); 1930fb515b0SLoGin } 1940fb515b0SLoGin 1950fb515b0SLoGin if o_flags.contains(FileMode::O_PATH) { 1960fb515b0SLoGin o_flags = o_flags.intersection(FileMode::O_PATH_FLAGS); 1970fb515b0SLoGin } 1980fb515b0SLoGin 1990fb515b0SLoGin Self { 2000fb515b0SLoGin o_flags, 2010fb515b0SLoGin mode, 2020fb515b0SLoGin resolve, 2030fb515b0SLoGin } 2040fb515b0SLoGin } 2050fb515b0SLoGin } 2060fb515b0SLoGin 2070fb515b0SLoGin impl From<PosixOpenHow> for OpenHow { 2080fb515b0SLoGin fn from(posix_open_how: PosixOpenHow) -> Self { 2090fb515b0SLoGin let o_flags = FileMode::from_bits_truncate(posix_open_how.flags as u32); 2100fb515b0SLoGin let mode = ModeType::from_bits_truncate(posix_open_how.mode as u32); 2110fb515b0SLoGin let resolve = OpenHowResolve::from_bits_truncate(posix_open_how.resolve as u64); 2120fb515b0SLoGin return Self::new(o_flags, mode, resolve); 2130fb515b0SLoGin } 2140fb515b0SLoGin } 2150fb515b0SLoGin 2160fb515b0SLoGin bitflags! { 2170fb515b0SLoGin pub struct OpenHowResolve: u64{ 2180fb515b0SLoGin /// Block mount-point crossings 2190fb515b0SLoGin /// (including bind-mounts). 2200fb515b0SLoGin const RESOLVE_NO_XDEV = 0x01; 2210fb515b0SLoGin 2220fb515b0SLoGin /// Block traversal through procfs-style 2230fb515b0SLoGin /// "magic-links" 2240fb515b0SLoGin const RESOLVE_NO_MAGICLINKS = 0x02; 2250fb515b0SLoGin 2260fb515b0SLoGin /// Block traversal through all symlinks 2270fb515b0SLoGin /// (implies OEXT_NO_MAGICLINKS) 2280fb515b0SLoGin const RESOLVE_NO_SYMLINKS = 0x04; 2290fb515b0SLoGin /// Block "lexical" trickery like 2300fb515b0SLoGin /// "..", symlinks, and absolute 2310fb515b0SLoGin const RESOLVE_BENEATH = 0x08; 2320fb515b0SLoGin /// Make all jumps to "/" and ".." 2330fb515b0SLoGin /// be scoped inside the dirfd 2340fb515b0SLoGin /// (similar to chroot(2)). 2350fb515b0SLoGin const RESOLVE_IN_ROOT = 0x10; 2360fb515b0SLoGin // Only complete if resolution can be 2370fb515b0SLoGin // completed through cached lookup. May 2380fb515b0SLoGin // return -EAGAIN if that's not 2390fb515b0SLoGin // possible. 2400fb515b0SLoGin const RESOLVE_CACHED = 0x20; 2410fb515b0SLoGin } 2420fb515b0SLoGin } 243ab5c8ca4Slogin impl Syscall { 244ab5c8ca4Slogin /// @brief 为当前进程打开一个文件 245ab5c8ca4Slogin /// 246ab5c8ca4Slogin /// @param path 文件路径 247ab5c8ca4Slogin /// @param o_flags 打开文件的标志位 248ab5c8ca4Slogin /// 249ab5c8ca4Slogin /// @return 文件描述符编号,或者是错误码 2500fb515b0SLoGin pub fn open( 2510fb515b0SLoGin path: &str, 2520fb515b0SLoGin flags: FileMode, 2530fb515b0SLoGin mode: ModeType, 2540fb515b0SLoGin follow_symlink: bool, 2550fb515b0SLoGin ) -> Result<usize, SystemError> { 2560fb515b0SLoGin return do_sys_open(AtFlags::AT_FDCWD.bits(), path, flags, mode, follow_symlink); 257ab5c8ca4Slogin } 258ab5c8ca4Slogin 2590fb515b0SLoGin pub fn openat( 2600fb515b0SLoGin dirfd: i32, 2610fb515b0SLoGin path: &str, 2620fb515b0SLoGin o_flags: FileMode, 2630fb515b0SLoGin mode: ModeType, 2640fb515b0SLoGin follow_symlink: bool, 2650fb515b0SLoGin ) -> Result<usize, SystemError> { 2660fb515b0SLoGin return do_sys_open(dirfd, path, o_flags, mode, follow_symlink); 267ab5c8ca4Slogin } 268ab5c8ca4Slogin 269ab5c8ca4Slogin /// @brief 关闭文件 270ab5c8ca4Slogin /// 271ab5c8ca4Slogin /// @param fd 文件描述符编号 272ab5c8ca4Slogin /// 273ab5c8ca4Slogin /// @return 成功返回0,失败返回错误码 274ab5c8ca4Slogin pub fn close(fd: usize) -> Result<usize, SystemError> { 2751496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 2761496ba7bSLoGin let mut fd_table_guard = binding.write(); 2771496ba7bSLoGin 27834e6d6c8Syuyi2439 let res = fd_table_guard.drop_fd(fd as i32).map(|_| 0); 27934e6d6c8Syuyi2439 28034e6d6c8Syuyi2439 return res; 281ab5c8ca4Slogin } 282ab5c8ca4Slogin 28340314b30SXiaoye Zheng /// @brief 发送命令到文件描述符对应的设备, 28440314b30SXiaoye Zheng /// 28540314b30SXiaoye Zheng /// @param fd 文件描述符编号 28640314b30SXiaoye Zheng /// @param cmd 设备相关的请求类型 28740314b30SXiaoye Zheng /// 28840314b30SXiaoye Zheng /// @return Ok(usize) 成功返回0 28940314b30SXiaoye Zheng /// @return Err(SystemError) 读取失败,返回posix错误码 29040314b30SXiaoye Zheng pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> { 29140314b30SXiaoye Zheng let binding = ProcessManager::current_pcb().fd_table(); 29240314b30SXiaoye Zheng let fd_table_guard = binding.read(); 29340314b30SXiaoye Zheng 29440314b30SXiaoye Zheng let file = fd_table_guard 29540314b30SXiaoye Zheng .get_file_by_fd(fd as i32) 29640314b30SXiaoye Zheng .ok_or(SystemError::EBADF)?; 29740314b30SXiaoye Zheng 29840314b30SXiaoye Zheng // drop guard 以避免无法调度的问题 29940314b30SXiaoye Zheng drop(fd_table_guard); 300*52da9a59SGnoCiYeH let file = file.lock_no_preempt(); 301*52da9a59SGnoCiYeH let r = file.inode().ioctl(cmd, data, &file.private_data); 30240314b30SXiaoye Zheng return r; 30340314b30SXiaoye Zheng } 30440314b30SXiaoye Zheng 305ab5c8ca4Slogin /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 306ab5c8ca4Slogin /// 307ab5c8ca4Slogin /// @param fd 文件描述符编号 30827b967a3S裕依 /// @param buf 输出缓冲区 309ab5c8ca4Slogin /// 310ab5c8ca4Slogin /// @return Ok(usize) 成功读取的数据的字节数 311ab5c8ca4Slogin /// @return Err(SystemError) 读取失败,返回posix错误码 312ab5c8ca4Slogin pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 3131496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 3141496ba7bSLoGin let fd_table_guard = binding.read(); 3151496ba7bSLoGin 3161496ba7bSLoGin let file = fd_table_guard.get_file_by_fd(fd); 317ab5c8ca4Slogin if file.is_none() { 318ab5c8ca4Slogin return Err(SystemError::EBADF); 319ab5c8ca4Slogin } 3201496ba7bSLoGin // drop guard 以避免无法调度的问题 3211496ba7bSLoGin drop(fd_table_guard); 3221496ba7bSLoGin let file = file.unwrap(); 323ab5c8ca4Slogin 3241496ba7bSLoGin return file.lock_no_preempt().read(buf.len(), buf); 325ab5c8ca4Slogin } 326ab5c8ca4Slogin 327ab5c8ca4Slogin /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 328ab5c8ca4Slogin /// 329ab5c8ca4Slogin /// @param fd 文件描述符编号 33027b967a3S裕依 /// @param buf 输入缓冲区 331ab5c8ca4Slogin /// 332ab5c8ca4Slogin /// @return Ok(usize) 成功写入的数据的字节数 333ab5c8ca4Slogin /// @return Err(SystemError) 写入失败,返回posix错误码 334ab5c8ca4Slogin pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 3351496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 3361496ba7bSLoGin let fd_table_guard = binding.read(); 337ab5c8ca4Slogin 3381496ba7bSLoGin let file = fd_table_guard 3391496ba7bSLoGin .get_file_by_fd(fd) 3401496ba7bSLoGin .ok_or(SystemError::EBADF)?; 3411496ba7bSLoGin 3421496ba7bSLoGin // drop guard 以避免无法调度的问题 3431496ba7bSLoGin drop(fd_table_guard); 3441496ba7bSLoGin return file.lock_no_preempt().write(buf.len(), buf); 345ab5c8ca4Slogin } 346ab5c8ca4Slogin 347ab5c8ca4Slogin /// @brief 调整文件操作指针的位置 348ab5c8ca4Slogin /// 349ab5c8ca4Slogin /// @param fd 文件描述符编号 350ab5c8ca4Slogin /// @param seek 调整的方式 351ab5c8ca4Slogin /// 352ab5c8ca4Slogin /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 353ab5c8ca4Slogin /// @return Err(SystemError) 调整失败,返回posix错误码 354ab5c8ca4Slogin pub fn lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> { 3551496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 3561496ba7bSLoGin let fd_table_guard = binding.read(); 3571496ba7bSLoGin let file = fd_table_guard 3581496ba7bSLoGin .get_file_by_fd(fd) 3591496ba7bSLoGin .ok_or(SystemError::EBADF)?; 3601496ba7bSLoGin 3611496ba7bSLoGin // drop guard 以避免无法调度的问题 3621496ba7bSLoGin drop(fd_table_guard); 3631496ba7bSLoGin return file.lock_no_preempt().lseek(seek); 364004e86ffSlogin } 365004e86ffSlogin 36627b967a3S裕依 /// # sys_pread64 系统调用的实际执行函数 36727b967a3S裕依 /// 36827b967a3S裕依 /// ## 参数 36927b967a3S裕依 /// - `fd`: 文件描述符 37027b967a3S裕依 /// - `buf`: 读出缓冲区 37127b967a3S裕依 /// - `len`: 要读取的字节数 37227b967a3S裕依 /// - `offset`: 文件偏移量 37327b967a3S裕依 pub fn pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError> { 37427b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 37527b967a3S裕依 let fd_table_guard = binding.read(); 37627b967a3S裕依 37727b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 37827b967a3S裕依 if file.is_none() { 37927b967a3S裕依 return Err(SystemError::EBADF); 38027b967a3S裕依 } 38127b967a3S裕依 // drop guard 以避免无法调度的问题 38227b967a3S裕依 drop(fd_table_guard); 38327b967a3S裕依 let file = file.unwrap(); 38427b967a3S裕依 38527b967a3S裕依 return file.lock_no_preempt().pread(offset, len, buf); 38627b967a3S裕依 } 38727b967a3S裕依 38827b967a3S裕依 /// # sys_pwrite64 系统调用的实际执行函数 38927b967a3S裕依 /// 39027b967a3S裕依 /// ## 参数 39127b967a3S裕依 /// - `fd`: 文件描述符 39227b967a3S裕依 /// - `buf`: 写入缓冲区 39327b967a3S裕依 /// - `len`: 要写入的字节数 39427b967a3S裕依 /// - `offset`: 文件偏移量 39527b967a3S裕依 pub fn pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError> { 39627b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 39727b967a3S裕依 let fd_table_guard = binding.read(); 39827b967a3S裕依 39927b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 40027b967a3S裕依 if file.is_none() { 40127b967a3S裕依 return Err(SystemError::EBADF); 40227b967a3S裕依 } 40327b967a3S裕依 // drop guard 以避免无法调度的问题 40427b967a3S裕依 drop(fd_table_guard); 40527b967a3S裕依 let file = file.unwrap(); 40627b967a3S裕依 40727b967a3S裕依 return file.lock_no_preempt().pwrite(offset, len, buf); 40827b967a3S裕依 } 40927b967a3S裕依 410004e86ffSlogin /// @brief 切换工作目录 411004e86ffSlogin /// 412004e86ffSlogin /// @param dest_path 目标路径 413004e86ffSlogin /// 414004e86ffSlogin /// @return 返回码 描述 415004e86ffSlogin /// 0 | 成功 416004e86ffSlogin /// 417004e86ffSlogin /// EACCESS | 权限不足 418004e86ffSlogin /// 419004e86ffSlogin /// ELOOP | 解析path时遇到路径循环 420004e86ffSlogin /// 421004e86ffSlogin /// ENAMETOOLONG | 路径名过长 422004e86ffSlogin /// 423004e86ffSlogin /// ENOENT | 目标文件或目录不存在 424004e86ffSlogin /// 425004e86ffSlogin /// ENODIR | 检索期间发现非目录项 426004e86ffSlogin /// 427004e86ffSlogin /// ENOMEM | 系统内存不足 428004e86ffSlogin /// 429004e86ffSlogin /// EFAULT | 错误的地址 430004e86ffSlogin /// 431004e86ffSlogin /// ENAMETOOLONG | 路径过长 432ab5c8ca4Slogin pub fn chdir(dest_path: &str) -> Result<usize, SystemError> { 4331496ba7bSLoGin let proc = ProcessManager::current_pcb(); 434ab5c8ca4Slogin // Copy path to kernel space to avoid some security issues 4351496ba7bSLoGin let path = dest_path.to_string(); 4361496ba7bSLoGin let mut new_path = String::from(""); 4371496ba7bSLoGin if path.len() > 0 { 4381496ba7bSLoGin let cwd = match path.as_bytes()[0] { 4391496ba7bSLoGin b'/' => String::from("/"), 4401496ba7bSLoGin _ => proc.basic().cwd(), 4411496ba7bSLoGin }; 4421496ba7bSLoGin let mut cwd_vec: Vec<_> = cwd.split("/").filter(|&x| x != "").collect(); 4431496ba7bSLoGin let path_split = path.split("/").filter(|&x| x != ""); 4441496ba7bSLoGin for seg in path_split { 4451496ba7bSLoGin if seg == ".." { 4461496ba7bSLoGin cwd_vec.pop(); 4471496ba7bSLoGin } else if seg == "." { 4481496ba7bSLoGin // 当前目录 4491496ba7bSLoGin } else { 4501496ba7bSLoGin cwd_vec.push(seg); 4511496ba7bSLoGin } 4521496ba7bSLoGin } 4531496ba7bSLoGin //proc.basic().set_path(String::from("")); 4541496ba7bSLoGin for seg in cwd_vec { 4551496ba7bSLoGin new_path.push_str("/"); 4561496ba7bSLoGin new_path.push_str(seg); 4571496ba7bSLoGin } 4581496ba7bSLoGin if new_path == "" { 4591496ba7bSLoGin new_path = String::from("/"); 4601496ba7bSLoGin } 4611496ba7bSLoGin } 462a03c4f9dSLoGin let inode = 463a03c4f9dSLoGin match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) { 464004e86ffSlogin Err(e) => { 465676b8ef6SMork kerror!("Change Directory Failed, Error = {:?}", e); 466ab5c8ca4Slogin return Err(SystemError::ENOENT); 467004e86ffSlogin } 468004e86ffSlogin Ok(i) => i, 469004e86ffSlogin }; 4701496ba7bSLoGin let metadata = inode.metadata()?; 4711496ba7bSLoGin if metadata.file_type == FileType::Dir { 4721496ba7bSLoGin proc.basic_mut().set_cwd(String::from(new_path)); 473ab5c8ca4Slogin return Ok(0); 474004e86ffSlogin } else { 475ab5c8ca4Slogin return Err(SystemError::ENOTDIR); 476004e86ffSlogin } 477004e86ffSlogin } 4781496ba7bSLoGin 4791496ba7bSLoGin /// @brief 获取当前进程的工作目录路径 4801496ba7bSLoGin /// 4811496ba7bSLoGin /// @param buf 指向缓冲区的指针 4821496ba7bSLoGin /// @param size 缓冲区的大小 4831496ba7bSLoGin /// 4841496ba7bSLoGin /// @return 成功,返回的指针指向包含工作目录路径的字符串 4851496ba7bSLoGin /// @return 错误,没有足够的空间 4861496ba7bSLoGin pub fn getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError> { 4871496ba7bSLoGin let proc = ProcessManager::current_pcb(); 4881496ba7bSLoGin let cwd = proc.basic().cwd(); 4891496ba7bSLoGin 4901496ba7bSLoGin let cwd_bytes = cwd.as_bytes(); 4911496ba7bSLoGin let cwd_len = cwd_bytes.len(); 4921496ba7bSLoGin if cwd_len + 1 > buf.len() { 4931496ba7bSLoGin return Err(SystemError::ENOMEM); 494004e86ffSlogin } 4951496ba7bSLoGin buf[..cwd_len].copy_from_slice(cwd_bytes); 4961496ba7bSLoGin buf[cwd_len] = 0; 4971496ba7bSLoGin 4981496ba7bSLoGin return Ok(VirtAddr::new(buf.as_ptr() as usize)); 499004e86ffSlogin } 500004e86ffSlogin 501004e86ffSlogin /// @brief 获取目录中的数据 502004e86ffSlogin /// 503ab5c8ca4Slogin /// TODO: 这个函数的语义与Linux不一致,需要修改!!! 504ab5c8ca4Slogin /// 505004e86ffSlogin /// @param fd 文件描述符号 506ab5c8ca4Slogin /// @param buf 输出缓冲区 507ab5c8ca4Slogin /// 508ab5c8ca4Slogin /// @return 成功返回读取的字节数,失败返回错误码 509ab5c8ca4Slogin pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 510ab5c8ca4Slogin let dirent = 511ab5c8ca4Slogin unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?; 512004e86ffSlogin 51346e234aeSLoGin if fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD { 514ab5c8ca4Slogin return Err(SystemError::EBADF); 515004e86ffSlogin } 516004e86ffSlogin 517004e86ffSlogin // 获取fd 5181496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5191496ba7bSLoGin let fd_table_guard = binding.read(); 5201496ba7bSLoGin let file = fd_table_guard 5211496ba7bSLoGin .get_file_by_fd(fd) 5221496ba7bSLoGin .ok_or(SystemError::EBADF)?; 523004e86ffSlogin 5241496ba7bSLoGin // drop guard 以避免无法调度的问题 5251496ba7bSLoGin drop(fd_table_guard); 52634e6d6c8Syuyi2439 52734e6d6c8Syuyi2439 let res = file.lock_no_preempt().readdir(dirent).map(|x| x as usize); 52834e6d6c8Syuyi2439 52934e6d6c8Syuyi2439 return res; 530004e86ffSlogin } 531004e86ffSlogin 532004e86ffSlogin /// @brief 创建文件夹 533004e86ffSlogin /// 534004e86ffSlogin /// @param path(r8) 路径 / mode(r9) 模式 535004e86ffSlogin /// 536004e86ffSlogin /// @return uint64_t 负数错误码 / 0表示成功 537ab5c8ca4Slogin pub fn mkdir(path: &str, mode: usize) -> Result<usize, SystemError> { 538ab5c8ca4Slogin return do_mkdir(path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize); 539004e86ffSlogin } 540004e86ffSlogin 541ab5c8ca4Slogin /// **删除文件夹、取消文件的链接、删除文件的系统调用** 542004e86ffSlogin /// 543ab5c8ca4Slogin /// ## 参数 544004e86ffSlogin /// 545ab5c8ca4Slogin /// - `dirfd`:文件夹的文件描述符.目前暂未实现 546ab5c8ca4Slogin /// - `pathname`:文件夹的路径 547ab5c8ca4Slogin /// - `flags`:标志位 548004e86ffSlogin /// 549004e86ffSlogin /// 550bf4a4899SLoGin pub fn unlinkat(dirfd: i32, pathname: &str, flags: u32) -> Result<usize, SystemError> { 551bf4a4899SLoGin let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?; 552004e86ffSlogin 553bf4a4899SLoGin if flags.contains(AtFlags::AT_REMOVEDIR) { 554004e86ffSlogin // kdebug!("rmdir"); 555bf4a4899SLoGin match do_remove_dir(dirfd, &pathname) { 556004e86ffSlogin Err(err) => { 557676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 558ab5c8ca4Slogin return Err(err); 559004e86ffSlogin } 560004e86ffSlogin Ok(_) => { 561ab5c8ca4Slogin return Ok(0); 562004e86ffSlogin } 563004e86ffSlogin } 564004e86ffSlogin } 565004e86ffSlogin 566bf4a4899SLoGin match do_unlink_at(dirfd, &pathname) { 567004e86ffSlogin Err(err) => { 568676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 569ab5c8ca4Slogin return Err(err); 570004e86ffSlogin } 571004e86ffSlogin Ok(_) => { 572ab5c8ca4Slogin return Ok(0); 573004e86ffSlogin } 574004e86ffSlogin } 575004e86ffSlogin } 5762b771e32SGou Ngai 577bf4a4899SLoGin pub fn unlink(pathname: *const u8) -> Result<usize, SystemError> { 578bf4a4899SLoGin if pathname.is_null() { 579bf4a4899SLoGin return Err(SystemError::EFAULT); 580bf4a4899SLoGin } 581bf4a4899SLoGin let ureader = UserBufferReader::new(pathname, MAX_PATHLEN, true)?; 582bf4a4899SLoGin 583bf4a4899SLoGin let buf: &[u8] = ureader.buffer(0).unwrap(); 584bf4a4899SLoGin 585bf4a4899SLoGin let pathname: &CStr = CStr::from_bytes_until_nul(buf).map_err(|_| SystemError::EINVAL)?; 586bf4a4899SLoGin 587bf4a4899SLoGin let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?; 588bf4a4899SLoGin if pathname.len() >= MAX_PATHLEN { 589bf4a4899SLoGin return Err(SystemError::ENAMETOOLONG); 590bf4a4899SLoGin } 591bf4a4899SLoGin let pathname = pathname.trim(); 592bf4a4899SLoGin 593bf4a4899SLoGin return do_unlink_at(AtFlags::AT_FDCWD.bits(), pathname).map(|v| v as usize); 594bf4a4899SLoGin } 595bf4a4899SLoGin 596ab5c8ca4Slogin /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd 597ab5c8ca4Slogin pub fn dup(oldfd: i32) -> Result<usize, SystemError> { 5981496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5991496ba7bSLoGin let mut fd_table_guard = binding.write(); 600ab5c8ca4Slogin 6011496ba7bSLoGin let old_file = fd_table_guard 6021496ba7bSLoGin .get_file_by_fd(oldfd) 6031496ba7bSLoGin .ok_or(SystemError::EBADF)?; 6041496ba7bSLoGin 6051496ba7bSLoGin let new_file = old_file 6061496ba7bSLoGin .lock_no_preempt() 6071496ba7bSLoGin .try_clone() 6081496ba7bSLoGin .ok_or(SystemError::EBADF)?; 6092b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 6101496ba7bSLoGin let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); 6112b771e32SGou Ngai return res; 6122b771e32SGou Ngai } 6132b771e32SGou Ngai 614ab5c8ca4Slogin /// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体, 615ab5c8ca4Slogin /// 并返回新复制的文件结构体对应的fd. 616ab5c8ca4Slogin /// 如果新fd已经打开,则会先关闭新fd. 617ab5c8ca4Slogin /// 618ab5c8ca4Slogin /// ## 参数 619ab5c8ca4Slogin /// 620ab5c8ca4Slogin /// - `oldfd`:旧文件描述符 621ab5c8ca4Slogin /// - `newfd`:新文件描述符 622ab5c8ca4Slogin /// 623ab5c8ca4Slogin /// ## 返回值 624ab5c8ca4Slogin /// 625ab5c8ca4Slogin /// - 成功:新文件描述符 626ab5c8ca4Slogin /// - 失败:错误码 627ab5c8ca4Slogin pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> { 6281496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6291496ba7bSLoGin let mut fd_table_guard = binding.write(); 6301496ba7bSLoGin return Self::do_dup2(oldfd, newfd, &mut fd_table_guard); 6311496ba7bSLoGin } 6321496ba7bSLoGin 6331496ba7bSLoGin fn do_dup2( 6341496ba7bSLoGin oldfd: i32, 6351496ba7bSLoGin newfd: i32, 6361496ba7bSLoGin fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, 6371496ba7bSLoGin ) -> Result<usize, SystemError> { 6382b771e32SGou Ngai // 确认oldfd, newid是否有效 6391496ba7bSLoGin if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) { 6401496ba7bSLoGin return Err(SystemError::EBADF); 6411496ba7bSLoGin } 6421496ba7bSLoGin 6432b771e32SGou Ngai if oldfd == newfd { 6442b771e32SGou Ngai // 若oldfd与newfd相等 645ab5c8ca4Slogin return Ok(newfd as usize); 6462b771e32SGou Ngai } 6471496ba7bSLoGin let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some(); 6481496ba7bSLoGin if new_exists { 6492b771e32SGou Ngai // close newfd 6501496ba7bSLoGin if let Err(_) = fd_table_guard.drop_fd(newfd) { 6512b771e32SGou Ngai // An I/O error occurred while attempting to close fildes2. 6522b771e32SGou Ngai return Err(SystemError::EIO); 6532b771e32SGou Ngai } 6542b771e32SGou Ngai } 6552b771e32SGou Ngai 6561496ba7bSLoGin let old_file = fd_table_guard 6571496ba7bSLoGin .get_file_by_fd(oldfd) 6581496ba7bSLoGin .ok_or(SystemError::EBADF)?; 6591496ba7bSLoGin let new_file = old_file 6601496ba7bSLoGin .lock_no_preempt() 6611496ba7bSLoGin .try_clone() 6621496ba7bSLoGin .ok_or(SystemError::EBADF)?; 6632b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 6641496ba7bSLoGin let res = fd_table_guard 6651496ba7bSLoGin .alloc_fd(new_file, Some(newfd)) 666ab5c8ca4Slogin .map(|x| x as usize); 6672b771e32SGou Ngai return res; 6682b771e32SGou Ngai } 6696d81180bSLoGin 6706d81180bSLoGin /// # fcntl 6716d81180bSLoGin /// 6726d81180bSLoGin /// ## 参数 6736d81180bSLoGin /// 6746d81180bSLoGin /// - `fd`:文件描述符 6756d81180bSLoGin /// - `cmd`:命令 6766d81180bSLoGin /// - `arg`:参数 6776d81180bSLoGin pub fn fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError> { 6786d81180bSLoGin match cmd { 6796d81180bSLoGin FcntlCommand::DupFd => { 6806d81180bSLoGin if arg < 0 || arg as usize >= FileDescriptorVec::PROCESS_MAX_FD { 6816d81180bSLoGin return Err(SystemError::EBADF); 6826d81180bSLoGin } 6836d81180bSLoGin let arg = arg as usize; 6846d81180bSLoGin for i in arg..FileDescriptorVec::PROCESS_MAX_FD { 6851496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6861496ba7bSLoGin let mut fd_table_guard = binding.write(); 687*52da9a59SGnoCiYeH if fd_table_guard.get_file_by_fd(i as i32).is_none() { 6881496ba7bSLoGin return Self::do_dup2(fd, i as i32, &mut fd_table_guard); 6896d81180bSLoGin } 6906d81180bSLoGin } 6916d81180bSLoGin return Err(SystemError::EMFILE); 6926d81180bSLoGin } 6936d81180bSLoGin FcntlCommand::GetFd => { 6946d81180bSLoGin // Get file descriptor flags. 6951496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6961496ba7bSLoGin let fd_table_guard = binding.read(); 6971496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 6981496ba7bSLoGin // drop guard 以避免无法调度的问题 6991496ba7bSLoGin drop(fd_table_guard); 7006d81180bSLoGin 7011496ba7bSLoGin if file.lock().close_on_exec() { 7026d81180bSLoGin return Ok(FD_CLOEXEC as usize); 7036d81180bSLoGin } 7046d81180bSLoGin } 7056d81180bSLoGin return Err(SystemError::EBADF); 7066d81180bSLoGin } 7076d81180bSLoGin FcntlCommand::SetFd => { 7086d81180bSLoGin // Set file descriptor flags. 7091496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7101496ba7bSLoGin let fd_table_guard = binding.write(); 7111496ba7bSLoGin 7121496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 7131496ba7bSLoGin // drop guard 以避免无法调度的问题 7141496ba7bSLoGin drop(fd_table_guard); 7156d81180bSLoGin let arg = arg as u32; 7166d81180bSLoGin if arg & FD_CLOEXEC != 0 { 7171496ba7bSLoGin file.lock().set_close_on_exec(true); 7186d81180bSLoGin } else { 7191496ba7bSLoGin file.lock().set_close_on_exec(false); 7206d81180bSLoGin } 7216d81180bSLoGin return Ok(0); 7226d81180bSLoGin } 7236d81180bSLoGin return Err(SystemError::EBADF); 7246d81180bSLoGin } 7256d81180bSLoGin 7266d81180bSLoGin FcntlCommand::GetFlags => { 7276d81180bSLoGin // Get file status flags. 7281496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7291496ba7bSLoGin let fd_table_guard = binding.read(); 7301496ba7bSLoGin 7311496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 7321496ba7bSLoGin // drop guard 以避免无法调度的问题 7331496ba7bSLoGin drop(fd_table_guard); 7341496ba7bSLoGin return Ok(file.lock_no_preempt().mode().bits() as usize); 7356d81180bSLoGin } 7361496ba7bSLoGin 7376d81180bSLoGin return Err(SystemError::EBADF); 7386d81180bSLoGin } 7396d81180bSLoGin FcntlCommand::SetFlags => { 7406d81180bSLoGin // Set file status flags. 7411496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7421496ba7bSLoGin let fd_table_guard = binding.write(); 7431496ba7bSLoGin 7441496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 7456d81180bSLoGin let arg = arg as u32; 7466d81180bSLoGin let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?; 7471496ba7bSLoGin // drop guard 以避免无法调度的问题 7481496ba7bSLoGin drop(fd_table_guard); 7491496ba7bSLoGin file.lock_no_preempt().set_mode(mode)?; 7506d81180bSLoGin return Ok(0); 7516d81180bSLoGin } 7521496ba7bSLoGin 7536d81180bSLoGin return Err(SystemError::EBADF); 7546d81180bSLoGin } 7556d81180bSLoGin _ => { 7566d81180bSLoGin // TODO: unimplemented 7576d81180bSLoGin // 未实现的命令,返回0,不报错。 7586d81180bSLoGin 7596d81180bSLoGin // kwarn!("fcntl: unimplemented command: {:?}, defaults to 0.", cmd); 7606d81180bSLoGin return Ok(0); 7616d81180bSLoGin } 7626d81180bSLoGin } 7636d81180bSLoGin } 7646d81180bSLoGin 7656d81180bSLoGin /// # ftruncate 7666d81180bSLoGin /// 7676d81180bSLoGin /// ## 描述 7686d81180bSLoGin /// 7696d81180bSLoGin /// 改变文件大小. 7706d81180bSLoGin /// 如果文件大小大于原来的大小,那么文件的内容将会被扩展到指定的大小,新的空间将会用0填充. 7716d81180bSLoGin /// 如果文件大小小于原来的大小,那么文件的内容将会被截断到指定的大小. 7726d81180bSLoGin /// 7736d81180bSLoGin /// ## 参数 7746d81180bSLoGin /// 7756d81180bSLoGin /// - `fd`:文件描述符 7766d81180bSLoGin /// - `len`:文件大小 7776d81180bSLoGin /// 7786d81180bSLoGin /// ## 返回值 7796d81180bSLoGin /// 7806d81180bSLoGin /// 如果成功,返回0,否则返回错误码. 7816d81180bSLoGin pub fn ftruncate(fd: i32, len: usize) -> Result<usize, SystemError> { 7821496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7831496ba7bSLoGin let fd_table_guard = binding.read(); 7841496ba7bSLoGin 7851496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 7861496ba7bSLoGin // drop guard 以避免无法调度的问题 7871496ba7bSLoGin drop(fd_table_guard); 7881496ba7bSLoGin let r = file.lock_no_preempt().ftruncate(len).map(|_| 0); 7896d81180bSLoGin return r; 7906d81180bSLoGin } 7911496ba7bSLoGin 7926d81180bSLoGin return Err(SystemError::EBADF); 7936d81180bSLoGin } 7941496ba7bSLoGin 79567b48188Shoumkh fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> { 7961496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7971496ba7bSLoGin let fd_table_guard = binding.read(); 7981496ba7bSLoGin let file = fd_table_guard 7991496ba7bSLoGin .get_file_by_fd(fd) 8001496ba7bSLoGin .ok_or(SystemError::EBADF)?; 8011496ba7bSLoGin // drop guard 以避免无法调度的问题 8021496ba7bSLoGin drop(fd_table_guard); 8031496ba7bSLoGin 80467b48188Shoumkh let mut kstat = PosixKstat::new(); 80567b48188Shoumkh // 获取文件信息 8061496ba7bSLoGin let metadata = file.lock().metadata()?; 80767b48188Shoumkh kstat.size = metadata.size as i64; 80867b48188Shoumkh kstat.dev_id = metadata.dev_id as u64; 8096b4e7a29SLoGin kstat.inode = metadata.inode_id.into() as u64; 81067b48188Shoumkh kstat.blcok_size = metadata.blk_size as i64; 81167b48188Shoumkh kstat.blocks = metadata.blocks as u64; 81267b48188Shoumkh 81367b48188Shoumkh kstat.atime.tv_sec = metadata.atime.tv_sec; 81467b48188Shoumkh kstat.atime.tv_nsec = metadata.atime.tv_nsec; 81567b48188Shoumkh kstat.mtime.tv_sec = metadata.mtime.tv_sec; 81667b48188Shoumkh kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; 81767b48188Shoumkh kstat.ctime.tv_sec = metadata.ctime.tv_sec; 81867b48188Shoumkh kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; 81967b48188Shoumkh 82067b48188Shoumkh kstat.nlink = metadata.nlinks as u64; 82167b48188Shoumkh kstat.uid = metadata.uid as i32; 82267b48188Shoumkh kstat.gid = metadata.gid as i32; 82302343d0bSLoGin kstat.rdev = metadata.raw_dev.data() as i64; 8246b4e7a29SLoGin kstat.mode = metadata.mode; 8251496ba7bSLoGin match file.lock().file_type() { 8267eda31b2SLoGin FileType::File => kstat.mode.insert(ModeType::S_IFREG), 82767b48188Shoumkh FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), 82867b48188Shoumkh FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), 82967b48188Shoumkh FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), 83067b48188Shoumkh FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), 83167b48188Shoumkh FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), 83267b48188Shoumkh FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), 83340314b30SXiaoye Zheng FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR), 83402343d0bSLoGin FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR), 83567b48188Shoumkh } 83667b48188Shoumkh 83767b48188Shoumkh return Ok(kstat); 83867b48188Shoumkh } 8391496ba7bSLoGin 84067b48188Shoumkh pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 8411496ba7bSLoGin let kstat = Self::do_fstat(fd)?; 84267b48188Shoumkh if usr_kstat.is_null() { 84367b48188Shoumkh return Err(SystemError::EFAULT); 84467b48188Shoumkh } 84567b48188Shoumkh unsafe { 84667b48188Shoumkh *usr_kstat = kstat; 84767b48188Shoumkh } 84867b48188Shoumkh return Ok(0); 84967b48188Shoumkh } 8502dbef785SGnoCiYeH 851971462beSGnoCiYeH pub fn stat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 8520fb515b0SLoGin let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), true)?; 853bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 854971462beSGnoCiYeH Self::close(fd).ok(); 855bf4a4899SLoGin return r; 856bf4a4899SLoGin } 857bf4a4899SLoGin 858bf4a4899SLoGin pub fn lstat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 8590fb515b0SLoGin let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), false)?; 860bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 861bf4a4899SLoGin Self::close(fd).ok(); 862bf4a4899SLoGin return r; 863971462beSGnoCiYeH } 864971462beSGnoCiYeH 8652dbef785SGnoCiYeH pub fn mknod( 8662dbef785SGnoCiYeH path_ptr: *const i8, 8672dbef785SGnoCiYeH mode: ModeType, 8682dbef785SGnoCiYeH dev_t: DeviceNumber, 8692dbef785SGnoCiYeH ) -> Result<usize, SystemError> { 8702dbef785SGnoCiYeH // 安全检验 8712dbef785SGnoCiYeH let len = unsafe { CStr::from_ptr(path_ptr).to_bytes().len() }; 8722dbef785SGnoCiYeH let user_buffer = UserBufferReader::new(path_ptr, len, true)?; 8732dbef785SGnoCiYeH let buf = user_buffer.read_from_user::<u8>(0)?; 8742dbef785SGnoCiYeH let path = core::str::from_utf8(buf).map_err(|_| SystemError::EINVAL)?; 8752dbef785SGnoCiYeH 8762dbef785SGnoCiYeH // 文件名过长 8772dbef785SGnoCiYeH if path.len() > MAX_PATHLEN as usize { 8782dbef785SGnoCiYeH return Err(SystemError::ENAMETOOLONG); 8792dbef785SGnoCiYeH } 8802dbef785SGnoCiYeH 881a03c4f9dSLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = 882a03c4f9dSLoGin ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 8832dbef785SGnoCiYeH 8842dbef785SGnoCiYeH if inode.is_ok() { 8852dbef785SGnoCiYeH return Err(SystemError::EEXIST); 8862dbef785SGnoCiYeH } 8872dbef785SGnoCiYeH 8882dbef785SGnoCiYeH let (filename, parent_path) = rsplit_path(path); 8892dbef785SGnoCiYeH 8902dbef785SGnoCiYeH // 查找父目录 891a03c4f9dSLoGin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE() 892a03c4f9dSLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 8932dbef785SGnoCiYeH // 创建nod 8942dbef785SGnoCiYeH parent_inode.mknod(filename, mode, dev_t)?; 8952dbef785SGnoCiYeH 8962dbef785SGnoCiYeH return Ok(0); 8972dbef785SGnoCiYeH } 898971462beSGnoCiYeH 899971462beSGnoCiYeH pub fn writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 900971462beSGnoCiYeH // IoVecs会进行用户态检验 901971462beSGnoCiYeH let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?; 902971462beSGnoCiYeH 903971462beSGnoCiYeH let data = iovecs.gather(); 904971462beSGnoCiYeH 905971462beSGnoCiYeH Self::write(fd, &data) 906971462beSGnoCiYeH } 907709498caSLoGin 908bf4a4899SLoGin pub fn readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 909bf4a4899SLoGin // IoVecs会进行用户态检验 910bf4a4899SLoGin let mut iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, true) }?; 911bf4a4899SLoGin 912bf4a4899SLoGin let mut data = Vec::new(); 913bf4a4899SLoGin data.resize(iovecs.0.iter().map(|x| x.len()).sum(), 0); 914bf4a4899SLoGin 915bf4a4899SLoGin let len = Self::read(fd, &mut data)?; 916bf4a4899SLoGin 917bf4a4899SLoGin iovecs.scatter(&data[..len]); 918bf4a4899SLoGin 919bf4a4899SLoGin return Ok(len); 920bf4a4899SLoGin } 921bf4a4899SLoGin 922709498caSLoGin pub fn readlink_at( 923709498caSLoGin dirfd: i32, 924709498caSLoGin path: *const u8, 925709498caSLoGin user_buf: *mut u8, 926709498caSLoGin buf_size: usize, 927709498caSLoGin ) -> Result<usize, SystemError> { 9289b0abe6dSLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 929709498caSLoGin let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?; 930709498caSLoGin 931709498caSLoGin if path.len() == 0 { 932709498caSLoGin return Err(SystemError::EINVAL); 93367b48188Shoumkh } 934709498caSLoGin 9350fb515b0SLoGin let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?; 936709498caSLoGin 937709498caSLoGin let inode = inode.lookup(path.as_str())?; 938709498caSLoGin if inode.metadata()?.file_type != FileType::SymLink { 939709498caSLoGin return Err(SystemError::EINVAL); 940709498caSLoGin } 941709498caSLoGin 942709498caSLoGin let ubuf = user_buf.buffer::<u8>(0).unwrap(); 943709498caSLoGin 944709498caSLoGin let mut file = File::new(inode, FileMode::O_RDONLY)?; 945709498caSLoGin 946709498caSLoGin let len = file.read(buf_size, ubuf)?; 947709498caSLoGin 948709498caSLoGin return Ok(len); 949709498caSLoGin } 950709498caSLoGin 951709498caSLoGin pub fn readlink( 952709498caSLoGin path: *const u8, 953709498caSLoGin user_buf: *mut u8, 954709498caSLoGin buf_size: usize, 955709498caSLoGin ) -> Result<usize, SystemError> { 9569b0abe6dSLoGin return Self::readlink_at(AtFlags::AT_FDCWD.bits(), path, user_buf, buf_size); 9579b0abe6dSLoGin } 9589b0abe6dSLoGin 9599b0abe6dSLoGin pub fn access(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 9609b0abe6dSLoGin return do_faccessat( 9619b0abe6dSLoGin AtFlags::AT_FDCWD.bits(), 9629b0abe6dSLoGin pathname, 963bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 9649b0abe6dSLoGin 0, 9659b0abe6dSLoGin ); 9669b0abe6dSLoGin } 9679b0abe6dSLoGin 9689b0abe6dSLoGin pub fn faccessat2( 9699b0abe6dSLoGin dirfd: i32, 9709b0abe6dSLoGin pathname: *const u8, 9719b0abe6dSLoGin mode: u32, 9729b0abe6dSLoGin flags: u32, 9739b0abe6dSLoGin ) -> Result<usize, SystemError> { 974bf4a4899SLoGin return do_faccessat( 975bf4a4899SLoGin dirfd, 976bf4a4899SLoGin pathname, 977bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 978bf4a4899SLoGin flags, 979bf4a4899SLoGin ); 980bf4a4899SLoGin } 981bf4a4899SLoGin 982bf4a4899SLoGin pub fn chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 983bf4a4899SLoGin return do_fchmodat( 984bf4a4899SLoGin AtFlags::AT_FDCWD.bits(), 985bf4a4899SLoGin pathname, 986bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 987bf4a4899SLoGin ); 988bf4a4899SLoGin } 989bf4a4899SLoGin 990bf4a4899SLoGin pub fn fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 991bf4a4899SLoGin return do_fchmodat( 992bf4a4899SLoGin dirfd, 993bf4a4899SLoGin pathname, 994bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 995bf4a4899SLoGin ); 996bf4a4899SLoGin } 997bf4a4899SLoGin 998bf4a4899SLoGin pub fn fchmod(fd: i32, mode: u32) -> Result<usize, SystemError> { 999bf4a4899SLoGin let _mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 1000bf4a4899SLoGin let binding = ProcessManager::current_pcb().fd_table(); 1001bf4a4899SLoGin let fd_table_guard = binding.read(); 1002bf4a4899SLoGin let _file = fd_table_guard 1003bf4a4899SLoGin .get_file_by_fd(fd) 1004bf4a4899SLoGin .ok_or(SystemError::EBADF)?; 1005bf4a4899SLoGin 1006bf4a4899SLoGin // fchmod没完全实现,因此不修改文件的权限 1007bf4a4899SLoGin // todo: 实现fchmod 1008bf4a4899SLoGin kwarn!("fchmod not fully implemented"); 1009bf4a4899SLoGin return Ok(0); 1010709498caSLoGin } 1011709498caSLoGin } 1012709498caSLoGin 1013cde5492fSlogin #[repr(C)] 1014cde5492fSlogin #[derive(Debug, Clone, Copy)] 1015cde5492fSlogin pub struct IoVec { 1016cde5492fSlogin /// 缓冲区的起始地址 1017cde5492fSlogin pub iov_base: *mut u8, 1018cde5492fSlogin /// 缓冲区的长度 1019cde5492fSlogin pub iov_len: usize, 1020cde5492fSlogin } 1021cde5492fSlogin 1022cde5492fSlogin /// 用于存储多个来自用户空间的IoVec 1023cde5492fSlogin /// 1024cde5492fSlogin /// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。 1025cde5492fSlogin /// TODO:支持分散读写 1026cde5492fSlogin #[derive(Debug)] 1027cde5492fSlogin pub struct IoVecs(Vec<&'static mut [u8]>); 1028cde5492fSlogin 1029cde5492fSlogin impl IoVecs { 1030cde5492fSlogin /// 从用户空间的IoVec中构造IoVecs 1031cde5492fSlogin /// 1032cde5492fSlogin /// @param iov 用户空间的IoVec 1033cde5492fSlogin /// @param iovcnt 用户空间的IoVec的数量 1034cde5492fSlogin /// @param readv 是否为readv系统调用 1035cde5492fSlogin /// 1036cde5492fSlogin /// @return 构造成功返回IoVecs,否则返回错误码 1037cde5492fSlogin pub unsafe fn from_user( 1038cde5492fSlogin iov: *const IoVec, 1039cde5492fSlogin iovcnt: usize, 1040cde5492fSlogin _readv: bool, 1041cde5492fSlogin ) -> Result<Self, SystemError> { 1042cde5492fSlogin // 检查iov指针所在空间是否合法 10434fda81ceSLoGin verify_area( 10444fda81ceSLoGin VirtAddr::new(iov as usize), 10454fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 10464fda81ceSLoGin ) 10474fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1048cde5492fSlogin 1049cde5492fSlogin // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) 1050cde5492fSlogin let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); 1051cde5492fSlogin 1052cde5492fSlogin let mut slices: Vec<&mut [u8]> = vec![]; 1053cde5492fSlogin slices.reserve(iovs.len()); 1054cde5492fSlogin 1055cde5492fSlogin for iov in iovs.iter() { 1056cde5492fSlogin if iov.iov_len == 0 { 1057cde5492fSlogin continue; 1058cde5492fSlogin } 1059cde5492fSlogin 10604fda81ceSLoGin verify_area( 10614fda81ceSLoGin VirtAddr::new(iov.iov_base as usize), 10624fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 10634fda81ceSLoGin ) 10644fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1065cde5492fSlogin 1066cde5492fSlogin slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); 1067cde5492fSlogin } 1068cde5492fSlogin 1069cde5492fSlogin return Ok(Self(slices)); 1070cde5492fSlogin } 1071cde5492fSlogin 1072cde5492fSlogin /// @brief 将IoVecs中的数据聚合到一个缓冲区中 1073cde5492fSlogin /// 1074cde5492fSlogin /// @return 返回聚合后的缓冲区 1075cde5492fSlogin pub fn gather(&self) -> Vec<u8> { 1076cde5492fSlogin let mut buf = Vec::new(); 1077cde5492fSlogin for slice in self.0.iter() { 1078cde5492fSlogin buf.extend_from_slice(slice); 1079cde5492fSlogin } 1080cde5492fSlogin return buf; 1081cde5492fSlogin } 1082cde5492fSlogin 1083cde5492fSlogin /// @brief 将给定的数据分散写入到IoVecs中 1084cde5492fSlogin pub fn scatter(&mut self, data: &[u8]) { 1085cde5492fSlogin let mut data: &[u8] = data; 1086cde5492fSlogin for slice in self.0.iter_mut() { 1087cde5492fSlogin let len = core::cmp::min(slice.len(), data.len()); 1088cde5492fSlogin if len == 0 { 1089cde5492fSlogin continue; 1090cde5492fSlogin } 1091cde5492fSlogin 1092cde5492fSlogin slice[..len].copy_from_slice(&data[..len]); 1093cde5492fSlogin data = &data[len..]; 1094cde5492fSlogin } 1095cde5492fSlogin } 1096cde5492fSlogin 1097cde5492fSlogin /// @brief 创建与IoVecs等长的缓冲区 1098cde5492fSlogin /// 1099cde5492fSlogin /// @param set_len 是否设置返回的Vec的len。 1100cde5492fSlogin /// 如果为true,则返回的Vec的len为所有IoVec的长度之和; 1101cde5492fSlogin /// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和. 1102cde5492fSlogin /// 1103cde5492fSlogin /// @return 返回创建的缓冲区 1104cde5492fSlogin pub fn new_buf(&self, set_len: bool) -> Vec<u8> { 1105cde5492fSlogin let total_len: usize = self.0.iter().map(|slice| slice.len()).sum(); 1106cde5492fSlogin let mut buf: Vec<u8> = Vec::with_capacity(total_len); 1107cde5492fSlogin 1108cde5492fSlogin if set_len { 11097ae679ddSLoGin buf.resize(total_len, 0); 1110cde5492fSlogin } 1111cde5492fSlogin return buf; 1112cde5492fSlogin } 1113cde5492fSlogin } 1114