1*1074eb34SSamuel Dai use core::cmp::Ordering; 2*1074eb34SSamuel Dai use core::fmt::Debug; 3*1074eb34SSamuel Dai use core::hash::Hash; 4*1074eb34SSamuel Dai 5*1074eb34SSamuel Dai use alloc::string::ToString; 69b0abe6dSLoGin use alloc::{string::String, sync::Arc}; 791e9d4abSLoGin use system_error::SystemError; 89b0abe6dSLoGin 991e9d4abSLoGin use crate::process::ProcessControlBlock; 109b0abe6dSLoGin 119b0abe6dSLoGin use super::{fcntl::AtFlags, FileType, IndexNode, ROOT_INODE}; 129b0abe6dSLoGin 13004e86ffSlogin /// @brief 切分路径字符串,返回最左侧那一级的目录名和剩余的部分。 14004e86ffSlogin /// 15004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为123, 第二个值为456/789 16bf4a4899SLoGin #[allow(dead_code)] 17004e86ffSlogin pub fn split_path(path: &str) -> (&str, Option<&str>) { 18004e86ffSlogin let mut path_split: core::str::SplitN<&str> = path.trim_matches('/').splitn(2, "/"); 19004e86ffSlogin let comp = path_split.next().unwrap_or(""); 20004e86ffSlogin let rest_opt = path_split.next(); 21004e86ffSlogin 22004e86ffSlogin return (comp, rest_opt); 23004e86ffSlogin } 24004e86ffSlogin 25004e86ffSlogin /// @brief 切分路径字符串,返回最右侧那一级的目录名和剩余的部分。 26004e86ffSlogin /// 27004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为789, 第二个值为123/456 28004e86ffSlogin pub fn rsplit_path(path: &str) -> (&str, Option<&str>) { 29004e86ffSlogin let mut path_split: core::str::RSplitN<&str> = path.trim_matches('/').rsplitn(2, "/"); 30004e86ffSlogin let comp = path_split.next().unwrap_or(""); 31004e86ffSlogin let rest_opt = path_split.next(); 32004e86ffSlogin 33004e86ffSlogin return (comp, rest_opt); 34004e86ffSlogin } 359b0abe6dSLoGin 369b0abe6dSLoGin /// 根据dirfd和path,计算接下来开始lookup的inode和剩余的path 379b0abe6dSLoGin /// 389b0abe6dSLoGin /// ## 返回值 399b0abe6dSLoGin /// 40bf4a4899SLoGin /// 返回值为(需要执行lookup的inode, 剩余的path) 419b0abe6dSLoGin pub fn user_path_at( 429b0abe6dSLoGin pcb: &Arc<ProcessControlBlock>, 439b0abe6dSLoGin dirfd: i32, 440fb515b0SLoGin path: &str, 459b0abe6dSLoGin ) -> Result<(Arc<dyn IndexNode>, String), SystemError> { 469b0abe6dSLoGin let mut inode = ROOT_INODE(); 470fb515b0SLoGin let ret_path; 489b0abe6dSLoGin // 如果path不是绝对路径,则需要拼接 499b0abe6dSLoGin if path.as_bytes()[0] != b'/' { 509b0abe6dSLoGin // 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录 519b0abe6dSLoGin if dirfd != AtFlags::AT_FDCWD.bits() { 529b0abe6dSLoGin let binding = pcb.fd_table(); 539b0abe6dSLoGin let fd_table_guard = binding.read(); 549b0abe6dSLoGin let file = fd_table_guard 559b0abe6dSLoGin .get_file_by_fd(dirfd) 569b0abe6dSLoGin .ok_or(SystemError::EBADF)?; 579b0abe6dSLoGin 589b0abe6dSLoGin // drop guard 以避免无法调度的问题 599b0abe6dSLoGin drop(fd_table_guard); 609b0abe6dSLoGin 619b0abe6dSLoGin // 如果dirfd不是目录,则返回错误码ENOTDIR 62dfe53cf0SGnoCiYeH if file.file_type() != FileType::Dir { 639b0abe6dSLoGin return Err(SystemError::ENOTDIR); 649b0abe6dSLoGin } 659b0abe6dSLoGin 66dfe53cf0SGnoCiYeH inode = file.inode(); 670fb515b0SLoGin ret_path = String::from(path); 689b0abe6dSLoGin } else { 699b0abe6dSLoGin let mut cwd = pcb.basic().cwd(); 709b0abe6dSLoGin cwd.push('/'); 710fb515b0SLoGin cwd.push_str(path); 720fb515b0SLoGin ret_path = cwd; 739b0abe6dSLoGin } 740fb515b0SLoGin } else { 750fb515b0SLoGin ret_path = String::from(path); 769b0abe6dSLoGin } 779b0abe6dSLoGin 780fb515b0SLoGin return Ok((inode, ret_path)); 799b0abe6dSLoGin } 80*1074eb34SSamuel Dai 81*1074eb34SSamuel Dai /// Directory Name 82*1074eb34SSamuel Dai /// 可以用来作为原地提取目录名及比较的 83*1074eb34SSamuel Dai /// Dentry的对标(x 84*1074eb34SSamuel Dai /// 85*1074eb34SSamuel Dai /// 简单的生成一个新的DName,以实现简单的RCU 86*1074eb34SSamuel Dai #[derive(Debug)] 87*1074eb34SSamuel Dai pub struct DName(pub Arc<String>); 88*1074eb34SSamuel Dai 89*1074eb34SSamuel Dai impl PartialEq for DName { 90*1074eb34SSamuel Dai fn eq(&self, other: &Self) -> bool { 91*1074eb34SSamuel Dai return *self.0 == *other.0; 92*1074eb34SSamuel Dai } 93*1074eb34SSamuel Dai } 94*1074eb34SSamuel Dai impl Eq for DName {} 95*1074eb34SSamuel Dai 96*1074eb34SSamuel Dai impl Hash for DName { 97*1074eb34SSamuel Dai fn hash<H: core::hash::Hasher>(&self, state: &mut H) { 98*1074eb34SSamuel Dai self.0.hash(state) 99*1074eb34SSamuel Dai } 100*1074eb34SSamuel Dai } 101*1074eb34SSamuel Dai 102*1074eb34SSamuel Dai impl PartialOrd for DName { 103*1074eb34SSamuel Dai fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 104*1074eb34SSamuel Dai Some(self.cmp(other)) 105*1074eb34SSamuel Dai } 106*1074eb34SSamuel Dai } 107*1074eb34SSamuel Dai 108*1074eb34SSamuel Dai impl Ord for DName { 109*1074eb34SSamuel Dai fn cmp(&self, other: &Self) -> Ordering { 110*1074eb34SSamuel Dai return self.0.cmp(&other.0); 111*1074eb34SSamuel Dai } 112*1074eb34SSamuel Dai } 113*1074eb34SSamuel Dai 114*1074eb34SSamuel Dai impl Default for DName { 115*1074eb34SSamuel Dai fn default() -> Self { 116*1074eb34SSamuel Dai Self(Arc::new(String::new())) 117*1074eb34SSamuel Dai } 118*1074eb34SSamuel Dai } 119*1074eb34SSamuel Dai 120*1074eb34SSamuel Dai impl From<String> for DName { 121*1074eb34SSamuel Dai fn from(value: String) -> Self { 122*1074eb34SSamuel Dai Self(Arc::from(value)) 123*1074eb34SSamuel Dai } 124*1074eb34SSamuel Dai } 125*1074eb34SSamuel Dai 126*1074eb34SSamuel Dai impl From<&str> for DName { 127*1074eb34SSamuel Dai fn from(value: &str) -> Self { 128*1074eb34SSamuel Dai Self(Arc::from(String::from(value))) 129*1074eb34SSamuel Dai } 130*1074eb34SSamuel Dai } 131*1074eb34SSamuel Dai 132*1074eb34SSamuel Dai impl Clone for DName { 133*1074eb34SSamuel Dai fn clone(&self) -> Self { 134*1074eb34SSamuel Dai Self(self.0.clone()) 135*1074eb34SSamuel Dai } 136*1074eb34SSamuel Dai } 137*1074eb34SSamuel Dai 138*1074eb34SSamuel Dai impl ToString for DName { 139*1074eb34SSamuel Dai fn to_string(&self) -> String { 140*1074eb34SSamuel Dai (*self.0).clone() 141*1074eb34SSamuel Dai } 142*1074eb34SSamuel Dai } 143*1074eb34SSamuel Dai 144*1074eb34SSamuel Dai impl AsRef<str> for DName { 145*1074eb34SSamuel Dai fn as_ref(&self) -> &str { 146*1074eb34SSamuel Dai self.0.as_str() 147*1074eb34SSamuel Dai } 148*1074eb34SSamuel Dai } 149