12dbef785SGnoCiYeH use core::ffi::CStr; 22dbef785SGnoCiYeH 31496ba7bSLoGin use alloc::{ 41496ba7bSLoGin string::{String, ToString}, 51496ba7bSLoGin sync::Arc, 61496ba7bSLoGin vec::Vec, 71496ba7bSLoGin }; 8004e86ffSlogin 9004e86ffSlogin use crate::{ 102dbef785SGnoCiYeH driver::base::{block::SeekFrom, device::DeviceNumber}, 112b771e32SGou Ngai filesystem::vfs::file::FileDescriptorVec, 12*bf4a4899SLoGin include::bindings::bindings::{verify_area, PROC_MAX_FD_NUM}, 132b771e32SGou Ngai kerror, 141496ba7bSLoGin libs::rwlock::RwLockWriteGuard, 151496ba7bSLoGin mm::VirtAddr, 161496ba7bSLoGin process::ProcessManager, 17709498caSLoGin syscall::{ 18709498caSLoGin user_access::{check_and_clone_cstr, UserBufferReader, UserBufferWriter}, 19709498caSLoGin Syscall, SystemError, 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}, 28*bf4a4899SLoGin open::{do_faccessat, do_fchmodat}, 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 } 149ab5c8ca4Slogin impl Syscall { 150ab5c8ca4Slogin /// @brief 为当前进程打开一个文件 151ab5c8ca4Slogin /// 152ab5c8ca4Slogin /// @param path 文件路径 153ab5c8ca4Slogin /// @param o_flags 打开文件的标志位 154ab5c8ca4Slogin /// 155ab5c8ca4Slogin /// @return 文件描述符编号,或者是错误码 156*bf4a4899SLoGin pub fn open(path: &str, mode: FileMode, follow_symlink: bool) -> Result<usize, SystemError> { 1576d81180bSLoGin // kdebug!("open: path: {}, mode: {:?}", path, mode); 158ab5c8ca4Slogin // 文件名过长 1592dbef785SGnoCiYeH if path.len() > MAX_PATHLEN as usize { 160ab5c8ca4Slogin return Err(SystemError::ENAMETOOLONG); 161ab5c8ca4Slogin } 162ab5c8ca4Slogin 163*bf4a4899SLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup_follow_symlink( 164*bf4a4899SLoGin path, 165*bf4a4899SLoGin if follow_symlink { 166*bf4a4899SLoGin VFS_MAX_FOLLOW_SYMLINK_TIMES 167*bf4a4899SLoGin } else { 168*bf4a4899SLoGin 0 169*bf4a4899SLoGin }, 170*bf4a4899SLoGin ); 171ab5c8ca4Slogin 172ab5c8ca4Slogin let inode: Arc<dyn IndexNode> = if inode.is_err() { 173ab5c8ca4Slogin let errno = inode.unwrap_err(); 174ab5c8ca4Slogin // 文件不存在,且需要创建 175ab5c8ca4Slogin if mode.contains(FileMode::O_CREAT) 176ab5c8ca4Slogin && !mode.contains(FileMode::O_DIRECTORY) 177ab5c8ca4Slogin && errno == SystemError::ENOENT 178ab5c8ca4Slogin { 179ab5c8ca4Slogin let (filename, parent_path) = rsplit_path(path); 180ab5c8ca4Slogin // 查找父目录 181ab5c8ca4Slogin let parent_inode: Arc<dyn IndexNode> = 182ab5c8ca4Slogin ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 183ab5c8ca4Slogin // 创建文件 1846b4e7a29SLoGin let inode: Arc<dyn IndexNode> = parent_inode.create( 1856b4e7a29SLoGin filename, 1866b4e7a29SLoGin FileType::File, 1876b4e7a29SLoGin ModeType::from_bits_truncate(0o755), 1886b4e7a29SLoGin )?; 189ab5c8ca4Slogin inode 190004e86ffSlogin } else { 191ab5c8ca4Slogin // 不需要创建文件,因此返回错误码 192ab5c8ca4Slogin return Err(errno); 193004e86ffSlogin } 194004e86ffSlogin } else { 195ab5c8ca4Slogin inode.unwrap() 196004e86ffSlogin }; 197004e86ffSlogin 198ab5c8ca4Slogin let file_type: FileType = inode.metadata()?.file_type; 199ab5c8ca4Slogin // 如果要打开的是文件夹,而目标不是文件夹 200ab5c8ca4Slogin if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir { 201ab5c8ca4Slogin return Err(SystemError::ENOTDIR); 202004e86ffSlogin } 203ab5c8ca4Slogin 204ab5c8ca4Slogin // 创建文件对象 20534e6d6c8Syuyi2439 206ab5c8ca4Slogin let mut file: File = File::new(inode, mode)?; 207ab5c8ca4Slogin 208ab5c8ca4Slogin // 打开模式为“追加” 209ab5c8ca4Slogin if mode.contains(FileMode::O_APPEND) { 210ab5c8ca4Slogin file.lseek(SeekFrom::SeekEnd(0))?; 211ab5c8ca4Slogin } 2120facf623SLoGin 2130facf623SLoGin // 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件 2140facf623SLoGin if mode.contains(FileMode::O_TRUNC) 2150facf623SLoGin && (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY)) 2160facf623SLoGin && file_type == FileType::File 2170facf623SLoGin { 2180facf623SLoGin file.ftruncate(0)?; 2190facf623SLoGin } 220ab5c8ca4Slogin // 把文件对象存入pcb 2211496ba7bSLoGin let r = ProcessManager::current_pcb() 2221496ba7bSLoGin .fd_table() 2231496ba7bSLoGin .write() 2241496ba7bSLoGin .alloc_fd(file, None) 2251496ba7bSLoGin .map(|fd| fd as usize); 2261496ba7bSLoGin 2276d81180bSLoGin return r; 228ab5c8ca4Slogin } 229ab5c8ca4Slogin 230ab5c8ca4Slogin /// @brief 关闭文件 231ab5c8ca4Slogin /// 232ab5c8ca4Slogin /// @param fd 文件描述符编号 233ab5c8ca4Slogin /// 234ab5c8ca4Slogin /// @return 成功返回0,失败返回错误码 235ab5c8ca4Slogin pub fn close(fd: usize) -> Result<usize, SystemError> { 2361496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 2371496ba7bSLoGin let mut fd_table_guard = binding.write(); 2381496ba7bSLoGin 23934e6d6c8Syuyi2439 let res = fd_table_guard.drop_fd(fd as i32).map(|_| 0); 24034e6d6c8Syuyi2439 24134e6d6c8Syuyi2439 return res; 242ab5c8ca4Slogin } 243ab5c8ca4Slogin 24440314b30SXiaoye Zheng /// @brief 发送命令到文件描述符对应的设备, 24540314b30SXiaoye Zheng /// 24640314b30SXiaoye Zheng /// @param fd 文件描述符编号 24740314b30SXiaoye Zheng /// @param cmd 设备相关的请求类型 24840314b30SXiaoye Zheng /// 24940314b30SXiaoye Zheng /// @return Ok(usize) 成功返回0 25040314b30SXiaoye Zheng /// @return Err(SystemError) 读取失败,返回posix错误码 25140314b30SXiaoye Zheng pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> { 25240314b30SXiaoye Zheng let binding = ProcessManager::current_pcb().fd_table(); 25340314b30SXiaoye Zheng let fd_table_guard = binding.read(); 25440314b30SXiaoye Zheng 25540314b30SXiaoye Zheng let file = fd_table_guard 25640314b30SXiaoye Zheng .get_file_by_fd(fd as i32) 25740314b30SXiaoye Zheng .ok_or(SystemError::EBADF)?; 25840314b30SXiaoye Zheng 25940314b30SXiaoye Zheng // drop guard 以避免无法调度的问题 26040314b30SXiaoye Zheng drop(fd_table_guard); 26140314b30SXiaoye Zheng let r = file.lock_no_preempt().inode().ioctl(cmd, data); 26240314b30SXiaoye Zheng return r; 26340314b30SXiaoye Zheng } 26440314b30SXiaoye Zheng 265ab5c8ca4Slogin /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 266ab5c8ca4Slogin /// 267ab5c8ca4Slogin /// @param fd 文件描述符编号 268ab5c8ca4Slogin /// @param buf 输出缓冲区。 269ab5c8ca4Slogin /// 270ab5c8ca4Slogin /// @return Ok(usize) 成功读取的数据的字节数 271ab5c8ca4Slogin /// @return Err(SystemError) 读取失败,返回posix错误码 272ab5c8ca4Slogin pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 2731496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 2741496ba7bSLoGin let fd_table_guard = binding.read(); 2751496ba7bSLoGin 2761496ba7bSLoGin let file = fd_table_guard.get_file_by_fd(fd); 277ab5c8ca4Slogin if file.is_none() { 278ab5c8ca4Slogin return Err(SystemError::EBADF); 279ab5c8ca4Slogin } 2801496ba7bSLoGin // drop guard 以避免无法调度的问题 2811496ba7bSLoGin drop(fd_table_guard); 2821496ba7bSLoGin let file = file.unwrap(); 283ab5c8ca4Slogin 2841496ba7bSLoGin return file.lock_no_preempt().read(buf.len(), buf); 285ab5c8ca4Slogin } 286ab5c8ca4Slogin 287ab5c8ca4Slogin /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 288ab5c8ca4Slogin /// 289ab5c8ca4Slogin /// @param fd 文件描述符编号 290ab5c8ca4Slogin /// @param buf 输入缓冲区。 291ab5c8ca4Slogin /// 292ab5c8ca4Slogin /// @return Ok(usize) 成功写入的数据的字节数 293ab5c8ca4Slogin /// @return Err(SystemError) 写入失败,返回posix错误码 294ab5c8ca4Slogin pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 2951496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 2961496ba7bSLoGin let fd_table_guard = binding.read(); 297ab5c8ca4Slogin 2981496ba7bSLoGin let file = fd_table_guard 2991496ba7bSLoGin .get_file_by_fd(fd) 3001496ba7bSLoGin .ok_or(SystemError::EBADF)?; 3011496ba7bSLoGin 3021496ba7bSLoGin // drop guard 以避免无法调度的问题 3031496ba7bSLoGin drop(fd_table_guard); 3041496ba7bSLoGin return file.lock_no_preempt().write(buf.len(), buf); 305ab5c8ca4Slogin } 306ab5c8ca4Slogin 307ab5c8ca4Slogin /// @brief 调整文件操作指针的位置 308ab5c8ca4Slogin /// 309ab5c8ca4Slogin /// @param fd 文件描述符编号 310ab5c8ca4Slogin /// @param seek 调整的方式 311ab5c8ca4Slogin /// 312ab5c8ca4Slogin /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 313ab5c8ca4Slogin /// @return Err(SystemError) 调整失败,返回posix错误码 314ab5c8ca4Slogin pub fn lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> { 3151496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 3161496ba7bSLoGin let fd_table_guard = binding.read(); 3171496ba7bSLoGin let file = fd_table_guard 3181496ba7bSLoGin .get_file_by_fd(fd) 3191496ba7bSLoGin .ok_or(SystemError::EBADF)?; 3201496ba7bSLoGin 3211496ba7bSLoGin // drop guard 以避免无法调度的问题 3221496ba7bSLoGin drop(fd_table_guard); 3231496ba7bSLoGin return file.lock_no_preempt().lseek(seek); 324004e86ffSlogin } 325004e86ffSlogin 326004e86ffSlogin /// @brief 切换工作目录 327004e86ffSlogin /// 328004e86ffSlogin /// @param dest_path 目标路径 329004e86ffSlogin /// 330004e86ffSlogin /// @return 返回码 描述 331004e86ffSlogin /// 0 | 成功 332004e86ffSlogin /// 333004e86ffSlogin /// EACCESS | 权限不足 334004e86ffSlogin /// 335004e86ffSlogin /// ELOOP | 解析path时遇到路径循环 336004e86ffSlogin /// 337004e86ffSlogin /// ENAMETOOLONG | 路径名过长 338004e86ffSlogin /// 339004e86ffSlogin /// ENOENT | 目标文件或目录不存在 340004e86ffSlogin /// 341004e86ffSlogin /// ENODIR | 检索期间发现非目录项 342004e86ffSlogin /// 343004e86ffSlogin /// ENOMEM | 系统内存不足 344004e86ffSlogin /// 345004e86ffSlogin /// EFAULT | 错误的地址 346004e86ffSlogin /// 347004e86ffSlogin /// ENAMETOOLONG | 路径过长 348ab5c8ca4Slogin pub fn chdir(dest_path: &str) -> Result<usize, SystemError> { 3491496ba7bSLoGin let proc = ProcessManager::current_pcb(); 350ab5c8ca4Slogin // Copy path to kernel space to avoid some security issues 3511496ba7bSLoGin let path = dest_path.to_string(); 3521496ba7bSLoGin let mut new_path = String::from(""); 3531496ba7bSLoGin if path.len() > 0 { 3541496ba7bSLoGin let cwd = match path.as_bytes()[0] { 3551496ba7bSLoGin b'/' => String::from("/"), 3561496ba7bSLoGin _ => proc.basic().cwd(), 3571496ba7bSLoGin }; 3581496ba7bSLoGin let mut cwd_vec: Vec<_> = cwd.split("/").filter(|&x| x != "").collect(); 3591496ba7bSLoGin let path_split = path.split("/").filter(|&x| x != ""); 3601496ba7bSLoGin for seg in path_split { 3611496ba7bSLoGin if seg == ".." { 3621496ba7bSLoGin cwd_vec.pop(); 3631496ba7bSLoGin } else if seg == "." { 3641496ba7bSLoGin // 当前目录 3651496ba7bSLoGin } else { 3661496ba7bSLoGin cwd_vec.push(seg); 3671496ba7bSLoGin } 3681496ba7bSLoGin } 3691496ba7bSLoGin //proc.basic().set_path(String::from("")); 3701496ba7bSLoGin for seg in cwd_vec { 3711496ba7bSLoGin new_path.push_str("/"); 3721496ba7bSLoGin new_path.push_str(seg); 3731496ba7bSLoGin } 3741496ba7bSLoGin if new_path == "" { 3751496ba7bSLoGin new_path = String::from("/"); 3761496ba7bSLoGin } 3771496ba7bSLoGin } 378a03c4f9dSLoGin let inode = 379a03c4f9dSLoGin match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) { 380004e86ffSlogin Err(e) => { 381676b8ef6SMork kerror!("Change Directory Failed, Error = {:?}", e); 382ab5c8ca4Slogin return Err(SystemError::ENOENT); 383004e86ffSlogin } 384004e86ffSlogin Ok(i) => i, 385004e86ffSlogin }; 3861496ba7bSLoGin let metadata = inode.metadata()?; 3871496ba7bSLoGin if metadata.file_type == FileType::Dir { 3881496ba7bSLoGin proc.basic_mut().set_cwd(String::from(new_path)); 389ab5c8ca4Slogin return Ok(0); 390004e86ffSlogin } else { 391ab5c8ca4Slogin return Err(SystemError::ENOTDIR); 392004e86ffSlogin } 393004e86ffSlogin } 3941496ba7bSLoGin 3951496ba7bSLoGin /// @brief 获取当前进程的工作目录路径 3961496ba7bSLoGin /// 3971496ba7bSLoGin /// @param buf 指向缓冲区的指针 3981496ba7bSLoGin /// @param size 缓冲区的大小 3991496ba7bSLoGin /// 4001496ba7bSLoGin /// @return 成功,返回的指针指向包含工作目录路径的字符串 4011496ba7bSLoGin /// @return 错误,没有足够的空间 4021496ba7bSLoGin pub fn getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError> { 4031496ba7bSLoGin let proc = ProcessManager::current_pcb(); 4041496ba7bSLoGin let cwd = proc.basic().cwd(); 4051496ba7bSLoGin 4061496ba7bSLoGin let cwd_bytes = cwd.as_bytes(); 4071496ba7bSLoGin let cwd_len = cwd_bytes.len(); 4081496ba7bSLoGin if cwd_len + 1 > buf.len() { 4091496ba7bSLoGin return Err(SystemError::ENOMEM); 410004e86ffSlogin } 4111496ba7bSLoGin buf[..cwd_len].copy_from_slice(cwd_bytes); 4121496ba7bSLoGin buf[cwd_len] = 0; 4131496ba7bSLoGin 4141496ba7bSLoGin return Ok(VirtAddr::new(buf.as_ptr() as usize)); 415004e86ffSlogin } 416004e86ffSlogin 417004e86ffSlogin /// @brief 获取目录中的数据 418004e86ffSlogin /// 419ab5c8ca4Slogin /// TODO: 这个函数的语义与Linux不一致,需要修改!!! 420ab5c8ca4Slogin /// 421004e86ffSlogin /// @param fd 文件描述符号 422ab5c8ca4Slogin /// @param buf 输出缓冲区 423ab5c8ca4Slogin /// 424ab5c8ca4Slogin /// @return 成功返回读取的字节数,失败返回错误码 425ab5c8ca4Slogin pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 426ab5c8ca4Slogin let dirent = 427ab5c8ca4Slogin unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?; 428004e86ffSlogin 429004e86ffSlogin if fd < 0 || fd as u32 > PROC_MAX_FD_NUM { 430ab5c8ca4Slogin return Err(SystemError::EBADF); 431004e86ffSlogin } 432004e86ffSlogin 433004e86ffSlogin // 获取fd 4341496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 4351496ba7bSLoGin let fd_table_guard = binding.read(); 4361496ba7bSLoGin let file = fd_table_guard 4371496ba7bSLoGin .get_file_by_fd(fd) 4381496ba7bSLoGin .ok_or(SystemError::EBADF)?; 439004e86ffSlogin 4401496ba7bSLoGin // drop guard 以避免无法调度的问题 4411496ba7bSLoGin drop(fd_table_guard); 44234e6d6c8Syuyi2439 44334e6d6c8Syuyi2439 let res = file.lock_no_preempt().readdir(dirent).map(|x| x as usize); 44434e6d6c8Syuyi2439 44534e6d6c8Syuyi2439 return res; 446004e86ffSlogin } 447004e86ffSlogin 448004e86ffSlogin /// @brief 创建文件夹 449004e86ffSlogin /// 450004e86ffSlogin /// @param path(r8) 路径 / mode(r9) 模式 451004e86ffSlogin /// 452004e86ffSlogin /// @return uint64_t 负数错误码 / 0表示成功 453ab5c8ca4Slogin pub fn mkdir(path: &str, mode: usize) -> Result<usize, SystemError> { 454ab5c8ca4Slogin return do_mkdir(path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize); 455004e86ffSlogin } 456004e86ffSlogin 457ab5c8ca4Slogin /// **删除文件夹、取消文件的链接、删除文件的系统调用** 458004e86ffSlogin /// 459ab5c8ca4Slogin /// ## 参数 460004e86ffSlogin /// 461ab5c8ca4Slogin /// - `dirfd`:文件夹的文件描述符.目前暂未实现 462ab5c8ca4Slogin /// - `pathname`:文件夹的路径 463ab5c8ca4Slogin /// - `flags`:标志位 464004e86ffSlogin /// 465004e86ffSlogin /// 466*bf4a4899SLoGin pub fn unlinkat(dirfd: i32, pathname: &str, flags: u32) -> Result<usize, SystemError> { 467*bf4a4899SLoGin let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?; 468004e86ffSlogin 469*bf4a4899SLoGin if flags.contains(AtFlags::AT_REMOVEDIR) { 470004e86ffSlogin // kdebug!("rmdir"); 471*bf4a4899SLoGin match do_remove_dir(dirfd, &pathname) { 472004e86ffSlogin Err(err) => { 473676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 474ab5c8ca4Slogin return Err(err); 475004e86ffSlogin } 476004e86ffSlogin Ok(_) => { 477ab5c8ca4Slogin return Ok(0); 478004e86ffSlogin } 479004e86ffSlogin } 480004e86ffSlogin } 481004e86ffSlogin 482*bf4a4899SLoGin match do_unlink_at(dirfd, &pathname) { 483004e86ffSlogin Err(err) => { 484676b8ef6SMork kerror!("Failed to Remove Directory, Error Code = {:?}", err); 485ab5c8ca4Slogin return Err(err); 486004e86ffSlogin } 487004e86ffSlogin Ok(_) => { 488ab5c8ca4Slogin return Ok(0); 489004e86ffSlogin } 490004e86ffSlogin } 491004e86ffSlogin } 4922b771e32SGou Ngai 493*bf4a4899SLoGin pub fn unlink(pathname: *const u8) -> Result<usize, SystemError> { 494*bf4a4899SLoGin if pathname.is_null() { 495*bf4a4899SLoGin return Err(SystemError::EFAULT); 496*bf4a4899SLoGin } 497*bf4a4899SLoGin let ureader = UserBufferReader::new(pathname, MAX_PATHLEN, true)?; 498*bf4a4899SLoGin 499*bf4a4899SLoGin let buf: &[u8] = ureader.buffer(0).unwrap(); 500*bf4a4899SLoGin 501*bf4a4899SLoGin let pathname: &CStr = CStr::from_bytes_until_nul(buf).map_err(|_| SystemError::EINVAL)?; 502*bf4a4899SLoGin 503*bf4a4899SLoGin let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?; 504*bf4a4899SLoGin if pathname.len() >= MAX_PATHLEN { 505*bf4a4899SLoGin return Err(SystemError::ENAMETOOLONG); 506*bf4a4899SLoGin } 507*bf4a4899SLoGin let pathname = pathname.trim(); 508*bf4a4899SLoGin 509*bf4a4899SLoGin return do_unlink_at(AtFlags::AT_FDCWD.bits(), pathname).map(|v| v as usize); 510*bf4a4899SLoGin } 511*bf4a4899SLoGin 512ab5c8ca4Slogin /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd 513ab5c8ca4Slogin pub fn dup(oldfd: i32) -> Result<usize, SystemError> { 5141496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5151496ba7bSLoGin let mut fd_table_guard = binding.write(); 516ab5c8ca4Slogin 5171496ba7bSLoGin let old_file = fd_table_guard 5181496ba7bSLoGin .get_file_by_fd(oldfd) 5191496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5201496ba7bSLoGin 5211496ba7bSLoGin let new_file = old_file 5221496ba7bSLoGin .lock_no_preempt() 5231496ba7bSLoGin .try_clone() 5241496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5252b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 5261496ba7bSLoGin let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); 5272b771e32SGou Ngai return res; 5282b771e32SGou Ngai } 5292b771e32SGou Ngai 530ab5c8ca4Slogin /// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体, 531ab5c8ca4Slogin /// 并返回新复制的文件结构体对应的fd. 532ab5c8ca4Slogin /// 如果新fd已经打开,则会先关闭新fd. 533ab5c8ca4Slogin /// 534ab5c8ca4Slogin /// ## 参数 535ab5c8ca4Slogin /// 536ab5c8ca4Slogin /// - `oldfd`:旧文件描述符 537ab5c8ca4Slogin /// - `newfd`:新文件描述符 538ab5c8ca4Slogin /// 539ab5c8ca4Slogin /// ## 返回值 540ab5c8ca4Slogin /// 541ab5c8ca4Slogin /// - 成功:新文件描述符 542ab5c8ca4Slogin /// - 失败:错误码 543ab5c8ca4Slogin pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> { 5441496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5451496ba7bSLoGin let mut fd_table_guard = binding.write(); 5461496ba7bSLoGin return Self::do_dup2(oldfd, newfd, &mut fd_table_guard); 5471496ba7bSLoGin } 5481496ba7bSLoGin 5491496ba7bSLoGin fn do_dup2( 5501496ba7bSLoGin oldfd: i32, 5511496ba7bSLoGin newfd: i32, 5521496ba7bSLoGin fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, 5531496ba7bSLoGin ) -> Result<usize, SystemError> { 5542b771e32SGou Ngai // 确认oldfd, newid是否有效 5551496ba7bSLoGin if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) { 5561496ba7bSLoGin return Err(SystemError::EBADF); 5571496ba7bSLoGin } 5581496ba7bSLoGin 5592b771e32SGou Ngai if oldfd == newfd { 5602b771e32SGou Ngai // 若oldfd与newfd相等 561ab5c8ca4Slogin return Ok(newfd as usize); 5622b771e32SGou Ngai } 5631496ba7bSLoGin let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some(); 5641496ba7bSLoGin if new_exists { 5652b771e32SGou Ngai // close newfd 5661496ba7bSLoGin if let Err(_) = fd_table_guard.drop_fd(newfd) { 5672b771e32SGou Ngai // An I/O error occurred while attempting to close fildes2. 5682b771e32SGou Ngai return Err(SystemError::EIO); 5692b771e32SGou Ngai } 5702b771e32SGou Ngai } 5712b771e32SGou Ngai 5721496ba7bSLoGin let old_file = fd_table_guard 5731496ba7bSLoGin .get_file_by_fd(oldfd) 5741496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5751496ba7bSLoGin let new_file = old_file 5761496ba7bSLoGin .lock_no_preempt() 5771496ba7bSLoGin .try_clone() 5781496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5792b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 5801496ba7bSLoGin let res = fd_table_guard 5811496ba7bSLoGin .alloc_fd(new_file, Some(newfd)) 582ab5c8ca4Slogin .map(|x| x as usize); 5832b771e32SGou Ngai return res; 5842b771e32SGou Ngai } 5856d81180bSLoGin 5866d81180bSLoGin /// # fcntl 5876d81180bSLoGin /// 5886d81180bSLoGin /// ## 参数 5896d81180bSLoGin /// 5906d81180bSLoGin /// - `fd`:文件描述符 5916d81180bSLoGin /// - `cmd`:命令 5926d81180bSLoGin /// - `arg`:参数 5936d81180bSLoGin pub fn fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError> { 5946d81180bSLoGin match cmd { 5956d81180bSLoGin FcntlCommand::DupFd => { 5966d81180bSLoGin if arg < 0 || arg as usize >= FileDescriptorVec::PROCESS_MAX_FD { 5976d81180bSLoGin return Err(SystemError::EBADF); 5986d81180bSLoGin } 5996d81180bSLoGin let arg = arg as usize; 6006d81180bSLoGin for i in arg..FileDescriptorVec::PROCESS_MAX_FD { 6011496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6021496ba7bSLoGin let mut fd_table_guard = binding.write(); 6031496ba7bSLoGin if fd_table_guard.get_file_by_fd(fd).is_none() { 6041496ba7bSLoGin return Self::do_dup2(fd, i as i32, &mut fd_table_guard); 6056d81180bSLoGin } 6066d81180bSLoGin } 6076d81180bSLoGin return Err(SystemError::EMFILE); 6086d81180bSLoGin } 6096d81180bSLoGin FcntlCommand::GetFd => { 6106d81180bSLoGin // Get file descriptor flags. 6111496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6121496ba7bSLoGin let fd_table_guard = binding.read(); 6131496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 6141496ba7bSLoGin // drop guard 以避免无法调度的问题 6151496ba7bSLoGin drop(fd_table_guard); 6166d81180bSLoGin 6171496ba7bSLoGin if file.lock().close_on_exec() { 6186d81180bSLoGin return Ok(FD_CLOEXEC as usize); 6196d81180bSLoGin } 6206d81180bSLoGin } 6216d81180bSLoGin return Err(SystemError::EBADF); 6226d81180bSLoGin } 6236d81180bSLoGin FcntlCommand::SetFd => { 6246d81180bSLoGin // Set file descriptor flags. 6251496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6261496ba7bSLoGin let fd_table_guard = binding.write(); 6271496ba7bSLoGin 6281496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 6291496ba7bSLoGin // drop guard 以避免无法调度的问题 6301496ba7bSLoGin drop(fd_table_guard); 6316d81180bSLoGin let arg = arg as u32; 6326d81180bSLoGin if arg & FD_CLOEXEC != 0 { 6331496ba7bSLoGin file.lock().set_close_on_exec(true); 6346d81180bSLoGin } else { 6351496ba7bSLoGin file.lock().set_close_on_exec(false); 6366d81180bSLoGin } 6376d81180bSLoGin return Ok(0); 6386d81180bSLoGin } 6396d81180bSLoGin return Err(SystemError::EBADF); 6406d81180bSLoGin } 6416d81180bSLoGin 6426d81180bSLoGin FcntlCommand::GetFlags => { 6436d81180bSLoGin // Get file status flags. 6441496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6451496ba7bSLoGin let fd_table_guard = binding.read(); 6461496ba7bSLoGin 6471496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 6481496ba7bSLoGin // drop guard 以避免无法调度的问题 6491496ba7bSLoGin drop(fd_table_guard); 6501496ba7bSLoGin return Ok(file.lock_no_preempt().mode().bits() as usize); 6516d81180bSLoGin } 6521496ba7bSLoGin 6536d81180bSLoGin return Err(SystemError::EBADF); 6546d81180bSLoGin } 6556d81180bSLoGin FcntlCommand::SetFlags => { 6566d81180bSLoGin // Set file status flags. 6571496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6581496ba7bSLoGin let fd_table_guard = binding.write(); 6591496ba7bSLoGin 6601496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 6616d81180bSLoGin let arg = arg as u32; 6626d81180bSLoGin let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?; 6631496ba7bSLoGin // drop guard 以避免无法调度的问题 6641496ba7bSLoGin drop(fd_table_guard); 6651496ba7bSLoGin file.lock_no_preempt().set_mode(mode)?; 6666d81180bSLoGin return Ok(0); 6676d81180bSLoGin } 6681496ba7bSLoGin 6696d81180bSLoGin return Err(SystemError::EBADF); 6706d81180bSLoGin } 6716d81180bSLoGin _ => { 6726d81180bSLoGin // TODO: unimplemented 6736d81180bSLoGin // 未实现的命令,返回0,不报错。 6746d81180bSLoGin 6756d81180bSLoGin // kwarn!("fcntl: unimplemented command: {:?}, defaults to 0.", cmd); 6766d81180bSLoGin return Ok(0); 6776d81180bSLoGin } 6786d81180bSLoGin } 6796d81180bSLoGin } 6806d81180bSLoGin 6816d81180bSLoGin /// # ftruncate 6826d81180bSLoGin /// 6836d81180bSLoGin /// ## 描述 6846d81180bSLoGin /// 6856d81180bSLoGin /// 改变文件大小. 6866d81180bSLoGin /// 如果文件大小大于原来的大小,那么文件的内容将会被扩展到指定的大小,新的空间将会用0填充. 6876d81180bSLoGin /// 如果文件大小小于原来的大小,那么文件的内容将会被截断到指定的大小. 6886d81180bSLoGin /// 6896d81180bSLoGin /// ## 参数 6906d81180bSLoGin /// 6916d81180bSLoGin /// - `fd`:文件描述符 6926d81180bSLoGin /// - `len`:文件大小 6936d81180bSLoGin /// 6946d81180bSLoGin /// ## 返回值 6956d81180bSLoGin /// 6966d81180bSLoGin /// 如果成功,返回0,否则返回错误码. 6976d81180bSLoGin pub fn ftruncate(fd: i32, len: usize) -> Result<usize, SystemError> { 6981496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6991496ba7bSLoGin let fd_table_guard = binding.read(); 7001496ba7bSLoGin 7011496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 7021496ba7bSLoGin // drop guard 以避免无法调度的问题 7031496ba7bSLoGin drop(fd_table_guard); 7041496ba7bSLoGin let r = file.lock_no_preempt().ftruncate(len).map(|_| 0); 7056d81180bSLoGin return r; 7066d81180bSLoGin } 7071496ba7bSLoGin 7086d81180bSLoGin return Err(SystemError::EBADF); 7096d81180bSLoGin } 7101496ba7bSLoGin 71167b48188Shoumkh fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> { 7121496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7131496ba7bSLoGin let fd_table_guard = binding.read(); 7141496ba7bSLoGin let file = fd_table_guard 7151496ba7bSLoGin .get_file_by_fd(fd) 7161496ba7bSLoGin .ok_or(SystemError::EBADF)?; 7171496ba7bSLoGin // drop guard 以避免无法调度的问题 7181496ba7bSLoGin drop(fd_table_guard); 7191496ba7bSLoGin 72067b48188Shoumkh let mut kstat = PosixKstat::new(); 72167b48188Shoumkh // 获取文件信息 7221496ba7bSLoGin let metadata = file.lock().metadata()?; 72367b48188Shoumkh kstat.size = metadata.size as i64; 72467b48188Shoumkh kstat.dev_id = metadata.dev_id as u64; 7256b4e7a29SLoGin kstat.inode = metadata.inode_id.into() as u64; 72667b48188Shoumkh kstat.blcok_size = metadata.blk_size as i64; 72767b48188Shoumkh kstat.blocks = metadata.blocks as u64; 72867b48188Shoumkh 72967b48188Shoumkh kstat.atime.tv_sec = metadata.atime.tv_sec; 73067b48188Shoumkh kstat.atime.tv_nsec = metadata.atime.tv_nsec; 73167b48188Shoumkh kstat.mtime.tv_sec = metadata.mtime.tv_sec; 73267b48188Shoumkh kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; 73367b48188Shoumkh kstat.ctime.tv_sec = metadata.ctime.tv_sec; 73467b48188Shoumkh kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; 73567b48188Shoumkh 73667b48188Shoumkh kstat.nlink = metadata.nlinks as u64; 73767b48188Shoumkh kstat.uid = metadata.uid as i32; 73867b48188Shoumkh kstat.gid = metadata.gid as i32; 73967b48188Shoumkh kstat.rdev = metadata.raw_dev as i64; 7406b4e7a29SLoGin kstat.mode = metadata.mode; 7411496ba7bSLoGin match file.lock().file_type() { 7427eda31b2SLoGin FileType::File => kstat.mode.insert(ModeType::S_IFREG), 74367b48188Shoumkh FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), 74467b48188Shoumkh FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), 74567b48188Shoumkh FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), 74667b48188Shoumkh FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), 74767b48188Shoumkh FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), 74867b48188Shoumkh FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), 74940314b30SXiaoye Zheng FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR), 75067b48188Shoumkh } 75167b48188Shoumkh 75267b48188Shoumkh return Ok(kstat); 75367b48188Shoumkh } 7541496ba7bSLoGin 75567b48188Shoumkh pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 7561496ba7bSLoGin let kstat = Self::do_fstat(fd)?; 75767b48188Shoumkh if usr_kstat.is_null() { 75867b48188Shoumkh return Err(SystemError::EFAULT); 75967b48188Shoumkh } 76067b48188Shoumkh unsafe { 76167b48188Shoumkh *usr_kstat = kstat; 76267b48188Shoumkh } 76367b48188Shoumkh return Ok(0); 76467b48188Shoumkh } 7652dbef785SGnoCiYeH 766971462beSGnoCiYeH pub fn stat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 767*bf4a4899SLoGin let fd = Self::open(path, FileMode::O_RDONLY, true)?; 768*bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 769971462beSGnoCiYeH Self::close(fd).ok(); 770*bf4a4899SLoGin return r; 771*bf4a4899SLoGin } 772*bf4a4899SLoGin 773*bf4a4899SLoGin pub fn lstat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 774*bf4a4899SLoGin let fd = Self::open(path, FileMode::O_RDONLY, false)?; 775*bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 776*bf4a4899SLoGin Self::close(fd).ok(); 777*bf4a4899SLoGin return r; 778971462beSGnoCiYeH } 779971462beSGnoCiYeH 7802dbef785SGnoCiYeH pub fn mknod( 7812dbef785SGnoCiYeH path_ptr: *const i8, 7822dbef785SGnoCiYeH mode: ModeType, 7832dbef785SGnoCiYeH dev_t: DeviceNumber, 7842dbef785SGnoCiYeH ) -> Result<usize, SystemError> { 7852dbef785SGnoCiYeH // 安全检验 7862dbef785SGnoCiYeH let len = unsafe { CStr::from_ptr(path_ptr).to_bytes().len() }; 7872dbef785SGnoCiYeH let user_buffer = UserBufferReader::new(path_ptr, len, true)?; 7882dbef785SGnoCiYeH let buf = user_buffer.read_from_user::<u8>(0)?; 7892dbef785SGnoCiYeH let path = core::str::from_utf8(buf).map_err(|_| SystemError::EINVAL)?; 7902dbef785SGnoCiYeH 7912dbef785SGnoCiYeH // 文件名过长 7922dbef785SGnoCiYeH if path.len() > MAX_PATHLEN as usize { 7932dbef785SGnoCiYeH return Err(SystemError::ENAMETOOLONG); 7942dbef785SGnoCiYeH } 7952dbef785SGnoCiYeH 796a03c4f9dSLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = 797a03c4f9dSLoGin ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 7982dbef785SGnoCiYeH 7992dbef785SGnoCiYeH if inode.is_ok() { 8002dbef785SGnoCiYeH return Err(SystemError::EEXIST); 8012dbef785SGnoCiYeH } 8022dbef785SGnoCiYeH 8032dbef785SGnoCiYeH let (filename, parent_path) = rsplit_path(path); 8042dbef785SGnoCiYeH 8052dbef785SGnoCiYeH // 查找父目录 806a03c4f9dSLoGin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE() 807a03c4f9dSLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 8082dbef785SGnoCiYeH // 创建nod 8092dbef785SGnoCiYeH parent_inode.mknod(filename, mode, dev_t)?; 8102dbef785SGnoCiYeH 8112dbef785SGnoCiYeH return Ok(0); 8122dbef785SGnoCiYeH } 813971462beSGnoCiYeH 814971462beSGnoCiYeH pub fn writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 815971462beSGnoCiYeH // IoVecs会进行用户态检验 816971462beSGnoCiYeH let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?; 817971462beSGnoCiYeH 818971462beSGnoCiYeH let data = iovecs.gather(); 819971462beSGnoCiYeH 820971462beSGnoCiYeH Self::write(fd, &data) 821971462beSGnoCiYeH } 822709498caSLoGin 823*bf4a4899SLoGin pub fn readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 824*bf4a4899SLoGin // IoVecs会进行用户态检验 825*bf4a4899SLoGin let mut iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, true) }?; 826*bf4a4899SLoGin 827*bf4a4899SLoGin let mut data = Vec::new(); 828*bf4a4899SLoGin data.resize(iovecs.0.iter().map(|x| x.len()).sum(), 0); 829*bf4a4899SLoGin 830*bf4a4899SLoGin let len = Self::read(fd, &mut data)?; 831*bf4a4899SLoGin 832*bf4a4899SLoGin iovecs.scatter(&data[..len]); 833*bf4a4899SLoGin 834*bf4a4899SLoGin return Ok(len); 835*bf4a4899SLoGin } 836*bf4a4899SLoGin 837709498caSLoGin pub fn readlink_at( 838709498caSLoGin dirfd: i32, 839709498caSLoGin path: *const u8, 840709498caSLoGin user_buf: *mut u8, 841709498caSLoGin buf_size: usize, 842709498caSLoGin ) -> Result<usize, SystemError> { 8439b0abe6dSLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 844709498caSLoGin let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?; 845709498caSLoGin 846709498caSLoGin if path.len() == 0 { 847709498caSLoGin return Err(SystemError::EINVAL); 84867b48188Shoumkh } 849709498caSLoGin 8509b0abe6dSLoGin let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?; 851709498caSLoGin 852709498caSLoGin let inode = inode.lookup(path.as_str())?; 853709498caSLoGin if inode.metadata()?.file_type != FileType::SymLink { 854709498caSLoGin return Err(SystemError::EINVAL); 855709498caSLoGin } 856709498caSLoGin 857709498caSLoGin let ubuf = user_buf.buffer::<u8>(0).unwrap(); 858709498caSLoGin 859709498caSLoGin let mut file = File::new(inode, FileMode::O_RDONLY)?; 860709498caSLoGin 861709498caSLoGin let len = file.read(buf_size, ubuf)?; 862709498caSLoGin 863709498caSLoGin return Ok(len); 864709498caSLoGin } 865709498caSLoGin 866709498caSLoGin pub fn readlink( 867709498caSLoGin path: *const u8, 868709498caSLoGin user_buf: *mut u8, 869709498caSLoGin buf_size: usize, 870709498caSLoGin ) -> Result<usize, SystemError> { 8719b0abe6dSLoGin return Self::readlink_at(AtFlags::AT_FDCWD.bits(), path, user_buf, buf_size); 8729b0abe6dSLoGin } 8739b0abe6dSLoGin 8749b0abe6dSLoGin pub fn access(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 8759b0abe6dSLoGin return do_faccessat( 8769b0abe6dSLoGin AtFlags::AT_FDCWD.bits(), 8779b0abe6dSLoGin pathname, 878*bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 8799b0abe6dSLoGin 0, 8809b0abe6dSLoGin ); 8819b0abe6dSLoGin } 8829b0abe6dSLoGin 8839b0abe6dSLoGin pub fn faccessat2( 8849b0abe6dSLoGin dirfd: i32, 8859b0abe6dSLoGin pathname: *const u8, 8869b0abe6dSLoGin mode: u32, 8879b0abe6dSLoGin flags: u32, 8889b0abe6dSLoGin ) -> Result<usize, SystemError> { 889*bf4a4899SLoGin return do_faccessat( 890*bf4a4899SLoGin dirfd, 891*bf4a4899SLoGin pathname, 892*bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 893*bf4a4899SLoGin flags, 894*bf4a4899SLoGin ); 895*bf4a4899SLoGin } 896*bf4a4899SLoGin 897*bf4a4899SLoGin pub fn chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 898*bf4a4899SLoGin return do_fchmodat( 899*bf4a4899SLoGin AtFlags::AT_FDCWD.bits(), 900*bf4a4899SLoGin pathname, 901*bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 902*bf4a4899SLoGin ); 903*bf4a4899SLoGin } 904*bf4a4899SLoGin 905*bf4a4899SLoGin pub fn fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 906*bf4a4899SLoGin return do_fchmodat( 907*bf4a4899SLoGin dirfd, 908*bf4a4899SLoGin pathname, 909*bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 910*bf4a4899SLoGin ); 911*bf4a4899SLoGin } 912*bf4a4899SLoGin 913*bf4a4899SLoGin pub fn fchmod(fd: i32, mode: u32) -> Result<usize, SystemError> { 914*bf4a4899SLoGin let _mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 915*bf4a4899SLoGin let binding = ProcessManager::current_pcb().fd_table(); 916*bf4a4899SLoGin let fd_table_guard = binding.read(); 917*bf4a4899SLoGin let _file = fd_table_guard 918*bf4a4899SLoGin .get_file_by_fd(fd) 919*bf4a4899SLoGin .ok_or(SystemError::EBADF)?; 920*bf4a4899SLoGin 921*bf4a4899SLoGin // fchmod没完全实现,因此不修改文件的权限 922*bf4a4899SLoGin // todo: 实现fchmod 923*bf4a4899SLoGin kwarn!("fchmod not fully implemented"); 924*bf4a4899SLoGin return Ok(0); 925709498caSLoGin } 926709498caSLoGin } 927709498caSLoGin 928cde5492fSlogin #[repr(C)] 929cde5492fSlogin #[derive(Debug, Clone, Copy)] 930cde5492fSlogin pub struct IoVec { 931cde5492fSlogin /// 缓冲区的起始地址 932cde5492fSlogin pub iov_base: *mut u8, 933cde5492fSlogin /// 缓冲区的长度 934cde5492fSlogin pub iov_len: usize, 935cde5492fSlogin } 936cde5492fSlogin 937cde5492fSlogin /// 用于存储多个来自用户空间的IoVec 938cde5492fSlogin /// 939cde5492fSlogin /// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。 940cde5492fSlogin /// TODO:支持分散读写 941cde5492fSlogin #[derive(Debug)] 942cde5492fSlogin pub struct IoVecs(Vec<&'static mut [u8]>); 943cde5492fSlogin 944cde5492fSlogin impl IoVecs { 945cde5492fSlogin /// 从用户空间的IoVec中构造IoVecs 946cde5492fSlogin /// 947cde5492fSlogin /// @param iov 用户空间的IoVec 948cde5492fSlogin /// @param iovcnt 用户空间的IoVec的数量 949cde5492fSlogin /// @param readv 是否为readv系统调用 950cde5492fSlogin /// 951cde5492fSlogin /// @return 构造成功返回IoVecs,否则返回错误码 952cde5492fSlogin pub unsafe fn from_user( 953cde5492fSlogin iov: *const IoVec, 954cde5492fSlogin iovcnt: usize, 955cde5492fSlogin _readv: bool, 956cde5492fSlogin ) -> Result<Self, SystemError> { 957cde5492fSlogin // 检查iov指针所在空间是否合法 958cde5492fSlogin if !verify_area( 959cde5492fSlogin iov as usize as u64, 960cde5492fSlogin (iovcnt * core::mem::size_of::<IoVec>()) as u64, 961cde5492fSlogin ) { 962cde5492fSlogin return Err(SystemError::EFAULT); 963cde5492fSlogin } 964cde5492fSlogin 965cde5492fSlogin // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) 966cde5492fSlogin let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); 967cde5492fSlogin 968cde5492fSlogin let mut slices: Vec<&mut [u8]> = vec![]; 969cde5492fSlogin slices.reserve(iovs.len()); 970cde5492fSlogin 971cde5492fSlogin for iov in iovs.iter() { 972cde5492fSlogin if iov.iov_len == 0 { 973cde5492fSlogin continue; 974cde5492fSlogin } 975cde5492fSlogin 976cde5492fSlogin if !verify_area(iov.iov_base as usize as u64, iov.iov_len as u64) { 977cde5492fSlogin return Err(SystemError::EFAULT); 978cde5492fSlogin } 979cde5492fSlogin 980cde5492fSlogin slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); 981cde5492fSlogin } 982cde5492fSlogin 983cde5492fSlogin return Ok(Self(slices)); 984cde5492fSlogin } 985cde5492fSlogin 986cde5492fSlogin /// @brief 将IoVecs中的数据聚合到一个缓冲区中 987cde5492fSlogin /// 988cde5492fSlogin /// @return 返回聚合后的缓冲区 989cde5492fSlogin pub fn gather(&self) -> Vec<u8> { 990cde5492fSlogin let mut buf = Vec::new(); 991cde5492fSlogin for slice in self.0.iter() { 992cde5492fSlogin buf.extend_from_slice(slice); 993cde5492fSlogin } 994cde5492fSlogin return buf; 995cde5492fSlogin } 996cde5492fSlogin 997cde5492fSlogin /// @brief 将给定的数据分散写入到IoVecs中 998cde5492fSlogin pub fn scatter(&mut self, data: &[u8]) { 999cde5492fSlogin let mut data: &[u8] = data; 1000cde5492fSlogin for slice in self.0.iter_mut() { 1001cde5492fSlogin let len = core::cmp::min(slice.len(), data.len()); 1002cde5492fSlogin if len == 0 { 1003cde5492fSlogin continue; 1004cde5492fSlogin } 1005cde5492fSlogin 1006cde5492fSlogin slice[..len].copy_from_slice(&data[..len]); 1007cde5492fSlogin data = &data[len..]; 1008cde5492fSlogin } 1009cde5492fSlogin } 1010cde5492fSlogin 1011cde5492fSlogin /// @brief 创建与IoVecs等长的缓冲区 1012cde5492fSlogin /// 1013cde5492fSlogin /// @param set_len 是否设置返回的Vec的len。 1014cde5492fSlogin /// 如果为true,则返回的Vec的len为所有IoVec的长度之和; 1015cde5492fSlogin /// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和. 1016cde5492fSlogin /// 1017cde5492fSlogin /// @return 返回创建的缓冲区 1018cde5492fSlogin pub fn new_buf(&self, set_len: bool) -> Vec<u8> { 1019cde5492fSlogin let total_len: usize = self.0.iter().map(|slice| slice.len()).sum(); 1020cde5492fSlogin let mut buf: Vec<u8> = Vec::with_capacity(total_len); 1021cde5492fSlogin 1022cde5492fSlogin if set_len { 10237ae679ddSLoGin buf.resize(total_len, 0); 1024cde5492fSlogin } 1025cde5492fSlogin return buf; 1026cde5492fSlogin } 1027cde5492fSlogin } 1028