1dfe53cf0SGnoCiYeH use core::sync::atomic::{AtomicUsize, Ordering}; 2dfe53cf0SGnoCiYeH 340609970SGnoCiYeH use alloc::{ 440609970SGnoCiYeH string::String, 540609970SGnoCiYeH sync::{Arc, Weak}, 640609970SGnoCiYeH vec::Vec, 740609970SGnoCiYeH }; 82eab6dd7S曾俊 use log::error; 991e9d4abSLoGin use system_error::SystemError; 10*cf7f801eSMemoryShore use xarray::XArray; 11004e86ffSlogin 124afc5b7bSlinfeng use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; 134afc5b7bSlinfeng use crate::filesystem::eventfd::EventFdInode; 14004e86ffSlogin use crate::{ 15*cf7f801eSMemoryShore arch::MMArch, 16b087521eSChiichen driver::{ 17b087521eSChiichen base::{block::SeekFrom, device::DevicePrivateData}, 1852da9a59SGnoCiYeH tty::tty_device::TtyFilePrivateData, 19b087521eSChiichen }, 20b087521eSChiichen filesystem::procfs::ProcfsFilePrivateData, 215e948c56SGnoCiYeH ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, 22dfe53cf0SGnoCiYeH libs::{rwlock::RwLock, spinlock::SpinLock}, 23*cf7f801eSMemoryShore mm::{page::Page, MemoryManagementArch}, 2440609970SGnoCiYeH net::{ 2540609970SGnoCiYeH event_poll::{EPollItem, EPollPrivateData, EventPoll}, 2640609970SGnoCiYeH socket::SocketInode, 2740609970SGnoCiYeH }, 280648a547SJomo process::{cred::Cred, ProcessManager}, 29004e86ffSlogin }; 30004e86ffSlogin 31004e86ffSlogin /// 文件私有信息的枚举类型 32004e86ffSlogin #[derive(Debug, Clone)] 33bf4a4899SLoGin #[allow(dead_code)] 34004e86ffSlogin pub enum FilePrivateData { 35876cb89eSGnoCiYeH /// 管道文件私有信息 36876cb89eSGnoCiYeH Pipefs(PipeFsPrivateData), 370d48c3c9Slogin /// procfs文件私有信息 38004e86ffSlogin Procfs(ProcfsFilePrivateData), 39b087521eSChiichen /// 设备文件的私有信息 40b087521eSChiichen DevFS(DevicePrivateData), 41b087521eSChiichen /// tty设备文件的私有信息 420d48c3c9Slogin Tty(TtyFilePrivateData), 4340609970SGnoCiYeH /// epoll私有信息 4440609970SGnoCiYeH EPoll(EPollPrivateData), 450d48c3c9Slogin /// 不需要文件私有信息 46004e86ffSlogin Unused, 47004e86ffSlogin } 48004e86ffSlogin 49004e86ffSlogin impl Default for FilePrivateData { default() -> Self50004e86ffSlogin fn default() -> Self { 51004e86ffSlogin return Self::Unused; 52004e86ffSlogin } 53004e86ffSlogin } 54004e86ffSlogin 555e948c56SGnoCiYeH impl FilePrivateData { update_mode(&mut self, mode: FileMode)565e948c56SGnoCiYeH pub fn update_mode(&mut self, mode: FileMode) { 575e948c56SGnoCiYeH if let FilePrivateData::Pipefs(pdata) = self { 585e948c56SGnoCiYeH pdata.set_mode(mode); 595e948c56SGnoCiYeH } 605e948c56SGnoCiYeH } 615e948c56SGnoCiYeH } 625e948c56SGnoCiYeH 63004e86ffSlogin bitflags! { 64004e86ffSlogin /// @brief 文件打开模式 65004e86ffSlogin /// 其中,低2bit组合而成的数字的值,用于表示访问权限。其他的bit,才支持通过按位或的方式来表示参数 66004e86ffSlogin /// 67004e86ffSlogin /// 与Linux 5.19.10的uapi/asm-generic/fcntl.h相同 68e7071df6SLoGin /// https://code.dragonos.org.cn/xref/linux-5.19.10/tools/include/uapi/asm-generic/fcntl.h#19 69b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 70004e86ffSlogin pub struct FileMode: u32{ 71004e86ffSlogin /* File access modes for `open' and `fcntl'. */ 72004e86ffSlogin /// Open Read-only 7384407d36Slogin const O_RDONLY = 0o0; 74004e86ffSlogin /// Open Write-only 7584407d36Slogin const O_WRONLY = 0o1; 76004e86ffSlogin /// Open read/write 7784407d36Slogin const O_RDWR = 0o2; 78004e86ffSlogin /// Mask for file access modes 7984407d36Slogin const O_ACCMODE = 0o00000003; 80004e86ffSlogin 81004e86ffSlogin /* Bits OR'd into the second argument to open. */ 82004e86ffSlogin /// Create file if it does not exist 8384407d36Slogin const O_CREAT = 0o00000100; 84004e86ffSlogin /// Fail if file already exists 8584407d36Slogin const O_EXCL = 0o00000200; 86004e86ffSlogin /// Do not assign controlling terminal 8784407d36Slogin const O_NOCTTY = 0o00000400; 88004e86ffSlogin /// 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空 8984407d36Slogin const O_TRUNC = 0o00001000; 90004e86ffSlogin /// 文件指针会被移动到文件末尾 9184407d36Slogin const O_APPEND = 0o00002000; 92004e86ffSlogin /// 非阻塞式IO模式 9384407d36Slogin const O_NONBLOCK = 0o00004000; 9420e3152eSlogin /// 每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新 9584407d36Slogin const O_DSYNC = 0o00010000; 96004e86ffSlogin /// fcntl, for BSD compatibility 9784407d36Slogin const FASYNC = 0o00020000; 98004e86ffSlogin /* direct disk access hint */ 9984407d36Slogin const O_DIRECT = 0o00040000; 10084407d36Slogin const O_LARGEFILE = 0o00100000; 101004e86ffSlogin /// 打开的必须是一个目录 10284407d36Slogin const O_DIRECTORY = 0o00200000; 103004e86ffSlogin /// Do not follow symbolic links 10484407d36Slogin const O_NOFOLLOW = 0o00400000; 10584407d36Slogin const O_NOATIME = 0o01000000; 106004e86ffSlogin /// set close_on_exec 10784407d36Slogin const O_CLOEXEC = 0o02000000; 10820e3152eSlogin /// 每次write都等到物理I/O完成,包括write引起的文件属性的更新 10920e3152eSlogin const O_SYNC = 0o04000000; 1100fb515b0SLoGin 1110fb515b0SLoGin const O_PATH = 0o10000000; 1120fb515b0SLoGin 1130fb515b0SLoGin const O_PATH_FLAGS = Self::O_DIRECTORY.bits|Self::O_NOFOLLOW.bits|Self::O_CLOEXEC.bits|Self::O_PATH.bits; 114004e86ffSlogin } 115004e86ffSlogin } 116004e86ffSlogin 11720e3152eSlogin impl FileMode { 11820e3152eSlogin /// @brief 获取文件的访问模式的值 11920e3152eSlogin #[inline] accmode(&self) -> u3212020e3152eSlogin pub fn accmode(&self) -> u32 { 12120e3152eSlogin return self.bits() & FileMode::O_ACCMODE.bits(); 12220e3152eSlogin } 12320e3152eSlogin } 124*cf7f801eSMemoryShore 125*cf7f801eSMemoryShore /// 页面缓存 126*cf7f801eSMemoryShore pub struct PageCache { 127*cf7f801eSMemoryShore xarray: SpinLock<XArray<Arc<Page>>>, 128*cf7f801eSMemoryShore inode: Option<Weak<dyn IndexNode>>, 129*cf7f801eSMemoryShore } 130*cf7f801eSMemoryShore 131*cf7f801eSMemoryShore impl core::fmt::Debug for PageCache { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result132*cf7f801eSMemoryShore fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 133*cf7f801eSMemoryShore f.debug_struct("PageCache") 134*cf7f801eSMemoryShore .field( 135*cf7f801eSMemoryShore "xarray", 136*cf7f801eSMemoryShore &self 137*cf7f801eSMemoryShore .xarray 138*cf7f801eSMemoryShore .lock() 139*cf7f801eSMemoryShore .range(0..((MMArch::PAGE_ADDRESS_SIZE >> MMArch::PAGE_SHIFT) as u64)) 140*cf7f801eSMemoryShore .map(|(_, r)| (*r).clone()) 141*cf7f801eSMemoryShore .collect::<Vec<Arc<Page>>>(), 142*cf7f801eSMemoryShore ) 143*cf7f801eSMemoryShore .finish() 144*cf7f801eSMemoryShore } 145*cf7f801eSMemoryShore } 146*cf7f801eSMemoryShore 147*cf7f801eSMemoryShore impl PageCache { new(inode: Option<Weak<dyn IndexNode>>) -> Arc<PageCache>148*cf7f801eSMemoryShore pub fn new(inode: Option<Weak<dyn IndexNode>>) -> Arc<PageCache> { 149*cf7f801eSMemoryShore let page_cache = Self { 150*cf7f801eSMemoryShore xarray: SpinLock::new(XArray::new()), 151*cf7f801eSMemoryShore inode, 152*cf7f801eSMemoryShore }; 153*cf7f801eSMemoryShore Arc::new(page_cache) 154*cf7f801eSMemoryShore } 155*cf7f801eSMemoryShore inode(&self) -> Option<Weak<dyn IndexNode>>156*cf7f801eSMemoryShore pub fn inode(&self) -> Option<Weak<dyn IndexNode>> { 157*cf7f801eSMemoryShore self.inode.clone() 158*cf7f801eSMemoryShore } 159*cf7f801eSMemoryShore add_page(&self, offset: usize, page: &Arc<Page>)160*cf7f801eSMemoryShore pub fn add_page(&self, offset: usize, page: &Arc<Page>) { 161*cf7f801eSMemoryShore let mut guard = self.xarray.lock(); 162*cf7f801eSMemoryShore let mut cursor = guard.cursor_mut(offset as u64); 163*cf7f801eSMemoryShore cursor.store(page.clone()); 164*cf7f801eSMemoryShore } 165*cf7f801eSMemoryShore get_page(&self, offset: usize) -> Option<Arc<Page>>166*cf7f801eSMemoryShore pub fn get_page(&self, offset: usize) -> Option<Arc<Page>> { 167*cf7f801eSMemoryShore let mut guard = self.xarray.lock(); 168*cf7f801eSMemoryShore let mut cursor = guard.cursor_mut(offset as u64); 169*cf7f801eSMemoryShore let page = cursor.load().map(|r| (*r).clone()); 170*cf7f801eSMemoryShore page 171*cf7f801eSMemoryShore } 172*cf7f801eSMemoryShore remove_page(&self, offset: usize)173*cf7f801eSMemoryShore pub fn remove_page(&self, offset: usize) { 174*cf7f801eSMemoryShore let mut guard = self.xarray.lock(); 175*cf7f801eSMemoryShore let mut cursor = guard.cursor_mut(offset as u64); 176*cf7f801eSMemoryShore cursor.remove(); 177*cf7f801eSMemoryShore } 178*cf7f801eSMemoryShore set_inode(&mut self, inode: Weak<dyn IndexNode>)179*cf7f801eSMemoryShore pub fn set_inode(&mut self, inode: Weak<dyn IndexNode>) { 180*cf7f801eSMemoryShore self.inode = Some(inode) 181*cf7f801eSMemoryShore } 182*cf7f801eSMemoryShore } 183*cf7f801eSMemoryShore 184004e86ffSlogin /// @brief 抽象文件结构体 18564aea4b3SGou Ngai #[derive(Debug)] 186004e86ffSlogin pub struct File { 187004e86ffSlogin inode: Arc<dyn IndexNode>, 188004e86ffSlogin /// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量 189dfe53cf0SGnoCiYeH offset: AtomicUsize, 190004e86ffSlogin /// 文件的打开模式 191dfe53cf0SGnoCiYeH mode: RwLock<FileMode>, 192004e86ffSlogin /// 文件类型 193004e86ffSlogin file_type: FileType, 194004e86ffSlogin /// readdir时候用的,暂存的本次循环中,所有子目录项的名字的数组 195dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock<Vec<String>>, 196dfe53cf0SGnoCiYeH pub private_data: SpinLock<FilePrivateData>, 1970648a547SJomo /// 文件的凭证 1980648a547SJomo cred: Cred, 199004e86ffSlogin } 200004e86ffSlogin 201004e86ffSlogin impl File { 202004e86ffSlogin /// @brief 创建一个新的文件对象 203004e86ffSlogin /// 204004e86ffSlogin /// @param inode 文件对象对应的inode 205004e86ffSlogin /// @param mode 文件的打开模式 new(inode: Arc<dyn IndexNode>, mode: FileMode) -> Result<Self, SystemError>206676b8ef6SMork pub fn new(inode: Arc<dyn IndexNode>, mode: FileMode) -> Result<Self, SystemError> { 2072dbef785SGnoCiYeH let mut inode = inode; 2082dbef785SGnoCiYeH let file_type = inode.metadata()?.file_type; 209b5b571e0SLoGin if file_type == FileType::Pipe { 2102dbef785SGnoCiYeH if let Some(SpecialNodeData::Pipe(pipe_inode)) = inode.special_node() { 2112dbef785SGnoCiYeH inode = pipe_inode; 2122dbef785SGnoCiYeH } 2132dbef785SGnoCiYeH } 2142dbef785SGnoCiYeH 215dfe53cf0SGnoCiYeH let f = File { 216004e86ffSlogin inode, 217dfe53cf0SGnoCiYeH offset: AtomicUsize::new(0), 218dfe53cf0SGnoCiYeH mode: RwLock::new(mode), 219004e86ffSlogin file_type, 220dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock::new(Vec::default()), 221dfe53cf0SGnoCiYeH private_data: SpinLock::new(FilePrivateData::default()), 2220648a547SJomo cred: ProcessManager::current_pcb().cred(), 223004e86ffSlogin }; 224dfe53cf0SGnoCiYeH f.inode.open(f.private_data.lock(), &mode)?; 22540314b30SXiaoye Zheng 226004e86ffSlogin return Ok(f); 227004e86ffSlogin } 228004e86ffSlogin 229004e86ffSlogin /// @brief 从文件中读取指定的字节数到buffer中 230004e86ffSlogin /// 231004e86ffSlogin /// @param len 要读取的字节数 232004e86ffSlogin /// @param buf 目标buffer 233004e86ffSlogin /// 234004e86ffSlogin /// @return Ok(usize) 成功读取的字节数 235676b8ef6SMork /// @return Err(SystemError) 错误码 read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>236dfe53cf0SGnoCiYeH pub fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> { 237dfe53cf0SGnoCiYeH self.do_read( 238dfe53cf0SGnoCiYeH self.offset.load(core::sync::atomic::Ordering::SeqCst), 239dfe53cf0SGnoCiYeH len, 240dfe53cf0SGnoCiYeH buf, 241dfe53cf0SGnoCiYeH true, 242dfe53cf0SGnoCiYeH ) 243004e86ffSlogin } 244004e86ffSlogin 245004e86ffSlogin /// @brief 从buffer向文件写入指定的字节数的数据 246004e86ffSlogin /// 247004e86ffSlogin /// @param len 要写入的字节数 248004e86ffSlogin /// @param buf 源数据buffer 249004e86ffSlogin /// 250004e86ffSlogin /// @return Ok(usize) 成功写入的字节数 251676b8ef6SMork /// @return Err(SystemError) 错误码 write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError>252dfe53cf0SGnoCiYeH pub fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> { 253dfe53cf0SGnoCiYeH self.do_write( 254dfe53cf0SGnoCiYeH self.offset.load(core::sync::atomic::Ordering::SeqCst), 255dfe53cf0SGnoCiYeH len, 256dfe53cf0SGnoCiYeH buf, 257dfe53cf0SGnoCiYeH true, 258dfe53cf0SGnoCiYeH ) 25927b967a3S裕依 } 26027b967a3S裕依 26127b967a3S裕依 /// ## 从文件中指定的偏移处读取指定的字节数到buf中 26227b967a3S裕依 /// 26327b967a3S裕依 /// ### 参数 26427b967a3S裕依 /// - `offset`: 文件偏移量 26527b967a3S裕依 /// - `len`: 要读取的字节数 26627b967a3S裕依 /// - `buf`: 读出缓冲区 26727b967a3S裕依 /// 26827b967a3S裕依 /// ### 返回值 26927b967a3S裕依 /// - `Ok(usize)`: 成功读取的字节数 pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>270dfe53cf0SGnoCiYeH pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> { 27127b967a3S裕依 self.do_read(offset, len, buf, false) 27227b967a3S裕依 } 27327b967a3S裕依 27427b967a3S裕依 /// ## 从buf向文件中指定的偏移处写入指定的字节数的数据 27527b967a3S裕依 /// 27627b967a3S裕依 /// ### 参数 27727b967a3S裕依 /// - `offset`: 文件偏移量 27827b967a3S裕依 /// - `len`: 要写入的字节数 27927b967a3S裕依 /// - `buf`: 写入缓冲区 28027b967a3S裕依 /// 28127b967a3S裕依 /// ### 返回值 28227b967a3S裕依 /// - `Ok(usize)`: 成功写入的字节数 pwrite(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError>283dfe53cf0SGnoCiYeH pub fn pwrite(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> { 28427b967a3S裕依 self.do_write(offset, len, buf, false) 28527b967a3S裕依 } 28627b967a3S裕依 do_read( &self, offset: usize, len: usize, buf: &mut [u8], update_offset: bool, ) -> Result<usize, SystemError>28727b967a3S裕依 fn do_read( 288dfe53cf0SGnoCiYeH &self, 28927b967a3S裕依 offset: usize, 29027b967a3S裕依 len: usize, 29127b967a3S裕依 buf: &mut [u8], 29227b967a3S裕依 update_offset: bool, 29327b967a3S裕依 ) -> Result<usize, SystemError> { 29427b967a3S裕依 // 先检查本文件在权限等规则下,是否可读取。 29527b967a3S裕依 self.readable()?; 29627b967a3S裕依 if buf.len() < len { 29727b967a3S裕依 return Err(SystemError::ENOBUFS); 29827b967a3S裕依 } 29927b967a3S裕依 30027b967a3S裕依 let len = self 30127b967a3S裕依 .inode 302dc9b4feaSLoGin .read_at(offset, len, buf, self.private_data.lock()) 303dc9b4feaSLoGin .map_err(|e| { 304dc9b4feaSLoGin if e == SystemError::ERESTARTSYS { 305dc9b4feaSLoGin SystemError::EINTR 306dc9b4feaSLoGin } else { 307dc9b4feaSLoGin e 308dc9b4feaSLoGin } 309dc9b4feaSLoGin })?; 31027b967a3S裕依 31127b967a3S裕依 if update_offset { 312dfe53cf0SGnoCiYeH self.offset 313dfe53cf0SGnoCiYeH .fetch_add(len, core::sync::atomic::Ordering::SeqCst); 31427b967a3S裕依 } 31527b967a3S裕依 31627b967a3S裕依 Ok(len) 31727b967a3S裕依 } 31827b967a3S裕依 do_write( &self, offset: usize, len: usize, buf: &[u8], update_offset: bool, ) -> Result<usize, SystemError>31927b967a3S裕依 fn do_write( 320dfe53cf0SGnoCiYeH &self, 32127b967a3S裕依 offset: usize, 32227b967a3S裕依 len: usize, 32327b967a3S裕依 buf: &[u8], 32427b967a3S裕依 update_offset: bool, 32527b967a3S裕依 ) -> Result<usize, SystemError> { 326004e86ffSlogin // 先检查本文件在权限等规则下,是否可写入。 327004e86ffSlogin self.writeable()?; 328004e86ffSlogin if buf.len() < len { 329676b8ef6SMork return Err(SystemError::ENOBUFS); 330004e86ffSlogin } 3316d81180bSLoGin 3326d81180bSLoGin // 如果文件指针已经超过了文件大小,则需要扩展文件大小 33327b967a3S裕依 if offset > self.inode.metadata()?.size as usize { 334dc9b4feaSLoGin self.inode.resize(offset).map_err(|e| { 335dc9b4feaSLoGin if e == SystemError::ERESTARTSYS { 336dc9b4feaSLoGin SystemError::EINTR 337dc9b4feaSLoGin } else { 338dc9b4feaSLoGin e 339dc9b4feaSLoGin } 340dc9b4feaSLoGin })?; 3416d81180bSLoGin } 342004e86ffSlogin let len = self 343004e86ffSlogin .inode 344dc9b4feaSLoGin .write_at(offset, len, buf, self.private_data.lock()) 345dc9b4feaSLoGin .map_err(|e| { 346dc9b4feaSLoGin if e == SystemError::ERESTARTSYS { 347dc9b4feaSLoGin SystemError::EINTR 348dc9b4feaSLoGin } else { 349dc9b4feaSLoGin e 350dc9b4feaSLoGin } 351dc9b4feaSLoGin })?; 35227b967a3S裕依 35327b967a3S裕依 if update_offset { 354dfe53cf0SGnoCiYeH self.offset 355dfe53cf0SGnoCiYeH .fetch_add(len, core::sync::atomic::Ordering::SeqCst); 35627b967a3S裕依 } 35727b967a3S裕依 35827b967a3S裕依 Ok(len) 359004e86ffSlogin } 360004e86ffSlogin 361004e86ffSlogin /// @brief 获取文件的元数据 metadata(&self) -> Result<Metadata, SystemError>362676b8ef6SMork pub fn metadata(&self) -> Result<Metadata, SystemError> { 363004e86ffSlogin return self.inode.metadata(); 364004e86ffSlogin } 365004e86ffSlogin 366004e86ffSlogin /// @brief 根据inode号获取子目录项的名字 367bf4a4899SLoGin #[allow(dead_code)] get_entry_name(&self, ino: InodeId) -> Result<String, SystemError>3686b4e7a29SLoGin pub fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 369004e86ffSlogin return self.inode.get_entry_name(ino); 370004e86ffSlogin } 371004e86ffSlogin 372004e86ffSlogin /// @brief 调整文件操作指针的位置 373004e86ffSlogin /// 374004e86ffSlogin /// @param origin 调整的起始位置 lseek(&self, origin: SeekFrom) -> Result<usize, SystemError>375dfe53cf0SGnoCiYeH pub fn lseek(&self, origin: SeekFrom) -> Result<usize, SystemError> { 37640fe15e0SLoGin let file_type = self.inode.metadata()?.file_type; 377bfafc102Slogin match file_type { 378bfafc102Slogin FileType::Pipe | FileType::CharDevice => { 379676b8ef6SMork return Err(SystemError::ESPIPE); 380004e86ffSlogin } 381bfafc102Slogin _ => {} 382bfafc102Slogin } 383bfafc102Slogin 384b5b571e0SLoGin let pos: i64 = match origin { 385b5b571e0SLoGin SeekFrom::SeekSet(offset) => offset, 386dfe53cf0SGnoCiYeH SeekFrom::SeekCurrent(offset) => self.offset.load(Ordering::SeqCst) as i64 + offset, 387004e86ffSlogin SeekFrom::SeekEnd(offset) => { 388004e86ffSlogin let metadata = self.metadata()?; 389b5b571e0SLoGin metadata.size + offset 390004e86ffSlogin } 391004e86ffSlogin SeekFrom::Invalid => { 392676b8ef6SMork return Err(SystemError::EINVAL); 393004e86ffSlogin } 394b5b571e0SLoGin }; 3956d81180bSLoGin // 根据linux man page, lseek允许超出文件末尾,并且不改变文件大小 3966d81180bSLoGin // 当pos超出文件末尾时,read返回0。直到开始写入数据时,才会改变文件大小 3976d81180bSLoGin if pos < 0 { 398676b8ef6SMork return Err(SystemError::EOVERFLOW); 399004e86ffSlogin } 400dfe53cf0SGnoCiYeH self.offset.store(pos as usize, Ordering::SeqCst); 401dfe53cf0SGnoCiYeH return Ok(pos as usize); 402004e86ffSlogin } 403004e86ffSlogin 404004e86ffSlogin /// @brief 判断当前文件是否可读 405004e86ffSlogin #[inline] readable(&self) -> Result<(), SystemError>406676b8ef6SMork pub fn readable(&self) -> Result<(), SystemError> { 407004e86ffSlogin // 暂时认为只要不是write only, 就可读 408dfe53cf0SGnoCiYeH if *self.mode.read() == FileMode::O_WRONLY { 409676b8ef6SMork return Err(SystemError::EPERM); 410004e86ffSlogin } 411004e86ffSlogin 412004e86ffSlogin return Ok(()); 413004e86ffSlogin } 414004e86ffSlogin 415004e86ffSlogin /// @brief 判断当前文件是否可写 416004e86ffSlogin #[inline] writeable(&self) -> Result<(), SystemError>417676b8ef6SMork pub fn writeable(&self) -> Result<(), SystemError> { 418004e86ffSlogin // 暂时认为只要不是read only, 就可写 419dfe53cf0SGnoCiYeH if *self.mode.read() == FileMode::O_RDONLY { 420676b8ef6SMork return Err(SystemError::EPERM); 421004e86ffSlogin } 422004e86ffSlogin 423004e86ffSlogin return Ok(()); 424004e86ffSlogin } 425004e86ffSlogin 426004e86ffSlogin /// @biref 充填dirent结构体 427004e86ffSlogin /// @return 返回dirent结构体的大小 readdir(&self, dirent: &mut Dirent) -> Result<u64, SystemError>428dfe53cf0SGnoCiYeH pub fn readdir(&self, dirent: &mut Dirent) -> Result<u64, SystemError> { 429004e86ffSlogin let inode: &Arc<dyn IndexNode> = &self.inode; 430dfe53cf0SGnoCiYeH let mut readdir_subdirs_name = self.readdir_subdirs_name.lock(); 431dfe53cf0SGnoCiYeH let offset = self.offset.load(Ordering::SeqCst); 432004e86ffSlogin // 如果偏移量为0 433dfe53cf0SGnoCiYeH if offset == 0 { 4341effcfe5SGnoCiYeH // 通过list更新readdir_subdirs_name 435dfe53cf0SGnoCiYeH *readdir_subdirs_name = inode.list()?; 436dfe53cf0SGnoCiYeH readdir_subdirs_name.sort(); 437004e86ffSlogin } 4382eab6dd7S曾俊 // debug!("sub_entries={sub_entries:?}"); 4391effcfe5SGnoCiYeH 4401effcfe5SGnoCiYeH // 已经读到末尾 441dfe53cf0SGnoCiYeH if offset == readdir_subdirs_name.len() { 442dfe53cf0SGnoCiYeH self.offset.store(0, Ordering::SeqCst); 443004e86ffSlogin return Ok(0); 444004e86ffSlogin } 445dfe53cf0SGnoCiYeH let name = &readdir_subdirs_name[offset]; 446b5b571e0SLoGin let sub_inode: Arc<dyn IndexNode> = match inode.find(name) { 447004e86ffSlogin Ok(i) => i, 448004e86ffSlogin Err(e) => { 4492eab6dd7S曾俊 error!( 45006d5e247SLoGin "Readdir error: Failed to find sub inode:{name:?}, file={self:?}, error={e:?}" 45106d5e247SLoGin ); 452004e86ffSlogin return Err(e); 453004e86ffSlogin } 454004e86ffSlogin }; 455004e86ffSlogin 456004e86ffSlogin let name_bytes: &[u8] = name.as_bytes(); 457004e86ffSlogin 458004e86ffSlogin // 根据posix的规定,dirent中的d_name是一个不定长的数组,因此需要unsafe来拷贝数据 459004e86ffSlogin unsafe { 460004e86ffSlogin let ptr = &mut dirent.d_name as *mut u8; 4611effcfe5SGnoCiYeH 462004e86ffSlogin let buf: &mut [u8] = 4631effcfe5SGnoCiYeH ::core::slice::from_raw_parts_mut::<'static, u8>(ptr, name_bytes.len() + 1); 4641effcfe5SGnoCiYeH buf[0..name_bytes.len()].copy_from_slice(name_bytes); 4651effcfe5SGnoCiYeH buf[name_bytes.len()] = 0; 466004e86ffSlogin } 467004e86ffSlogin 468dfe53cf0SGnoCiYeH self.offset.fetch_add(1, Ordering::SeqCst); 4691effcfe5SGnoCiYeH dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64; 4701effcfe5SGnoCiYeH dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8; 4711effcfe5SGnoCiYeH 472004e86ffSlogin // 计算dirent结构体的大小 473bb0e4d41SGnoCiYeH let size = (name_bytes.len() + ::core::mem::size_of::<Dirent>() 474bb0e4d41SGnoCiYeH - ::core::mem::size_of_val(&dirent.d_name)) as u64; 475bb0e4d41SGnoCiYeH 476bb0e4d41SGnoCiYeH dirent.d_reclen = size as u16; 477bb0e4d41SGnoCiYeH dirent.d_off += dirent.d_reclen as i64; 478bb0e4d41SGnoCiYeH 479bb0e4d41SGnoCiYeH return Ok(size); 480004e86ffSlogin } 48164aea4b3SGou Ngai inode(&self) -> Arc<dyn IndexNode>482004e86ffSlogin pub fn inode(&self) -> Arc<dyn IndexNode> { 483004e86ffSlogin return self.inode.clone(); 484004e86ffSlogin } 48564aea4b3SGou Ngai 48664aea4b3SGou Ngai /// @brief 尝试克隆一个文件 48764aea4b3SGou Ngai /// 4881496ba7bSLoGin /// @return Option<File> 克隆后的文件结构体。如果克隆失败,返回None try_clone(&self) -> Option<File>4891496ba7bSLoGin pub fn try_clone(&self) -> Option<File> { 490dfe53cf0SGnoCiYeH let res = Self { 49164aea4b3SGou Ngai inode: self.inode.clone(), 492dfe53cf0SGnoCiYeH offset: AtomicUsize::new(self.offset.load(Ordering::SeqCst)), 493dfe53cf0SGnoCiYeH mode: RwLock::new(self.mode()), 494b5b571e0SLoGin file_type: self.file_type, 495dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock::new(self.readdir_subdirs_name.lock().clone()), 496dfe53cf0SGnoCiYeH private_data: SpinLock::new(self.private_data.lock().clone()), 4970648a547SJomo cred: self.cred.clone(), 4981496ba7bSLoGin }; 49964aea4b3SGou Ngai // 调用inode的open方法,让inode知道有新的文件打开了这个inode 500dfe53cf0SGnoCiYeH if self 501dfe53cf0SGnoCiYeH .inode 502dfe53cf0SGnoCiYeH .open(res.private_data.lock(), &res.mode()) 503dfe53cf0SGnoCiYeH .is_err() 504dfe53cf0SGnoCiYeH { 50564aea4b3SGou Ngai return None; 50664aea4b3SGou Ngai } 50764aea4b3SGou Ngai 50864aea4b3SGou Ngai return Some(res); 50964aea4b3SGou Ngai } 510cde5492fSlogin 511cde5492fSlogin /// @brief 获取文件的类型 512cde5492fSlogin #[inline] file_type(&self) -> FileType513cde5492fSlogin pub fn file_type(&self) -> FileType { 514cde5492fSlogin return self.file_type; 515cde5492fSlogin } 5166d81180bSLoGin 5176d81180bSLoGin /// @brief 获取文件的打开模式 5186d81180bSLoGin #[inline] mode(&self) -> FileMode5196d81180bSLoGin pub fn mode(&self) -> FileMode { 520dfe53cf0SGnoCiYeH return *self.mode.read(); 5216d81180bSLoGin } 5226d81180bSLoGin 5236d81180bSLoGin /// 获取文件是否在execve时关闭 5246d81180bSLoGin #[inline] close_on_exec(&self) -> bool5256d81180bSLoGin pub fn close_on_exec(&self) -> bool { 526dfe53cf0SGnoCiYeH return self.mode().contains(FileMode::O_CLOEXEC); 5276d81180bSLoGin } 5286d81180bSLoGin 5296d81180bSLoGin /// 设置文件是否在execve时关闭 5306d81180bSLoGin #[inline] set_close_on_exec(&self, close_on_exec: bool)531dfe53cf0SGnoCiYeH pub fn set_close_on_exec(&self, close_on_exec: bool) { 532dfe53cf0SGnoCiYeH let mut mode_guard = self.mode.write(); 5336d81180bSLoGin if close_on_exec { 534dfe53cf0SGnoCiYeH mode_guard.insert(FileMode::O_CLOEXEC); 5356d81180bSLoGin } else { 536dfe53cf0SGnoCiYeH mode_guard.remove(FileMode::O_CLOEXEC); 5376d81180bSLoGin } 5386d81180bSLoGin } 5396d81180bSLoGin set_mode(&self, mode: FileMode) -> Result<(), SystemError>540dfe53cf0SGnoCiYeH pub fn set_mode(&self, mode: FileMode) -> Result<(), SystemError> { 5416d81180bSLoGin // todo: 是否需要调用inode的open方法,以更新private data(假如它与mode有关的话)? 5426d81180bSLoGin // 也许需要加个更好的设计,让inode知晓文件的打开模式发生了变化,让它自己决定是否需要更新private data 5436d81180bSLoGin 5446d81180bSLoGin // 直接修改文件的打开模式 545dfe53cf0SGnoCiYeH *self.mode.write() = mode; 546dfe53cf0SGnoCiYeH self.private_data.lock().update_mode(mode); 5476d81180bSLoGin return Ok(()); 5486d81180bSLoGin } 5496d81180bSLoGin 5506d81180bSLoGin /// @brief 重新设置文件的大小 5516d81180bSLoGin /// 5526d81180bSLoGin /// 如果文件大小增加,则文件内容不变,但是文件的空洞部分会被填充为0 5536d81180bSLoGin /// 如果文件大小减小,则文件内容会被截断 5546d81180bSLoGin /// 5556d81180bSLoGin /// @return 成功:Ok() 5566d81180bSLoGin /// 失败:Err(错误码) ftruncate(&self, len: usize) -> Result<(), SystemError>5571496ba7bSLoGin pub fn ftruncate(&self, len: usize) -> Result<(), SystemError> { 5586d81180bSLoGin // 如果文件不可写,返回错误 5596d81180bSLoGin self.writeable()?; 5606d81180bSLoGin 5616d81180bSLoGin // 调用inode的truncate方法 5626d81180bSLoGin self.inode.resize(len)?; 5636d81180bSLoGin return Ok(()); 5646d81180bSLoGin } 56540609970SGnoCiYeH 56640609970SGnoCiYeH /// ## 向该文件添加一个EPollItem对象 56740609970SGnoCiYeH /// 56840609970SGnoCiYeH /// 在文件状态发生变化时,需要向epoll通知 add_epoll(&self, epitem: Arc<EPollItem>) -> Result<(), SystemError>569dfe53cf0SGnoCiYeH pub fn add_epoll(&self, epitem: Arc<EPollItem>) -> Result<(), SystemError> { 57040609970SGnoCiYeH match self.file_type { 57140609970SGnoCiYeH FileType::Socket => { 57240609970SGnoCiYeH let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); 57340609970SGnoCiYeH let mut socket = inode.inner(); 57440609970SGnoCiYeH 57540609970SGnoCiYeH return socket.add_epoll(epitem); 57640609970SGnoCiYeH } 5775e948c56SGnoCiYeH FileType::Pipe => { 5785e948c56SGnoCiYeH let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap(); 5795e948c56SGnoCiYeH return inode.inner().lock().add_epoll(epitem); 5805e948c56SGnoCiYeH } 58152bcb59eSGnoCiYeH _ => { 582415e14e9Slaokengwt let r = self.inode.kernel_ioctl(epitem, &self.private_data.lock()); 58352bcb59eSGnoCiYeH if r.is_err() { 58452bcb59eSGnoCiYeH return Err(SystemError::ENOSYS); 58552bcb59eSGnoCiYeH } 58652bcb59eSGnoCiYeH 58752bcb59eSGnoCiYeH Ok(()) 58852bcb59eSGnoCiYeH } 58940609970SGnoCiYeH } 59040609970SGnoCiYeH } 59140609970SGnoCiYeH 59240609970SGnoCiYeH /// ## 删除一个绑定的epoll remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError>593dfe53cf0SGnoCiYeH pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> { 59440609970SGnoCiYeH match self.file_type { 59540609970SGnoCiYeH FileType::Socket => { 59640609970SGnoCiYeH let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); 59740609970SGnoCiYeH let mut socket = inode.inner(); 59840609970SGnoCiYeH 5994afc5b7bSlinfeng socket.remove_epoll(epoll) 60040609970SGnoCiYeH } 6014afc5b7bSlinfeng FileType::Pipe => { 6024afc5b7bSlinfeng let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap(); 6034afc5b7bSlinfeng inode.inner().lock().remove_epoll(epoll) 6044afc5b7bSlinfeng } 6054afc5b7bSlinfeng _ => { 6064afc5b7bSlinfeng let inode = self 6074afc5b7bSlinfeng .inode 6084afc5b7bSlinfeng .downcast_ref::<EventFdInode>() 6094afc5b7bSlinfeng .ok_or(SystemError::ENOSYS)?; 6104afc5b7bSlinfeng inode.remove_epoll(epoll) 6114afc5b7bSlinfeng } 61240609970SGnoCiYeH } 61340609970SGnoCiYeH } 61440609970SGnoCiYeH poll(&self) -> Result<usize, SystemError>61540609970SGnoCiYeH pub fn poll(&self) -> Result<usize, SystemError> { 616dfe53cf0SGnoCiYeH self.inode.poll(&self.private_data.lock()) 61740609970SGnoCiYeH } 618004e86ffSlogin } 619004e86ffSlogin 620004e86ffSlogin impl Drop for File { drop(&mut self)621004e86ffSlogin fn drop(&mut self) { 622dfe53cf0SGnoCiYeH let r: Result<(), SystemError> = self.inode.close(self.private_data.lock()); 623004e86ffSlogin // 打印错误信息 624004e86ffSlogin if r.is_err() { 6252eab6dd7S曾俊 error!( 6261496ba7bSLoGin "pid: {:?} failed to close file: {:?}, errno={:?}", 6271496ba7bSLoGin ProcessManager::current_pcb().pid(), 628004e86ffSlogin self, 6298d72b68dSJomo r.as_ref().unwrap_err() 630004e86ffSlogin ); 631004e86ffSlogin } 632004e86ffSlogin } 633004e86ffSlogin } 634004e86ffSlogin 635004e86ffSlogin /// @brief pcb里面的文件描述符数组 63664aea4b3SGou Ngai #[derive(Debug)] 637004e86ffSlogin pub struct FileDescriptorVec { 638004e86ffSlogin /// 当前进程打开的文件描述符 639dfe53cf0SGnoCiYeH fds: Vec<Option<Arc<File>>>, 640004e86ffSlogin } 641dc9b4feaSLoGin impl Default for FileDescriptorVec { default() -> Self642dc9b4feaSLoGin fn default() -> Self { 643dc9b4feaSLoGin Self::new() 644dc9b4feaSLoGin } 645dc9b4feaSLoGin } 646004e86ffSlogin impl FileDescriptorVec { 6470d9b7d92SLoGin pub const PROCESS_MAX_FD: usize = 1024; 648004e86ffSlogin 6494fda81ceSLoGin #[inline(never)] new() -> FileDescriptorVec6501496ba7bSLoGin pub fn new() -> FileDescriptorVec { 6514fda81ceSLoGin let mut data = Vec::with_capacity(FileDescriptorVec::PROCESS_MAX_FD); 6524fda81ceSLoGin data.resize(FileDescriptorVec::PROCESS_MAX_FD, None); 653004e86ffSlogin 654004e86ffSlogin // 初始化文件描述符数组结构体 6551496ba7bSLoGin return FileDescriptorVec { fds: data }; 656004e86ffSlogin } 657004e86ffSlogin 65864aea4b3SGou Ngai /// @brief 克隆一个文件描述符数组 65964aea4b3SGou Ngai /// 6601496ba7bSLoGin /// @return FileDescriptorVec 克隆后的文件描述符数组 clone(&self) -> FileDescriptorVec6611496ba7bSLoGin pub fn clone(&self) -> FileDescriptorVec { 6621496ba7bSLoGin let mut res = FileDescriptorVec::new(); 66364aea4b3SGou Ngai for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 66464aea4b3SGou Ngai if let Some(file) = &self.fds[i] { 665dfe53cf0SGnoCiYeH if let Some(file) = file.try_clone() { 666dfe53cf0SGnoCiYeH res.fds[i] = Some(Arc::new(file)); 6671496ba7bSLoGin } 66864aea4b3SGou Ngai } 66964aea4b3SGou Ngai } 67064aea4b3SGou Ngai return res; 67164aea4b3SGou Ngai } 67264aea4b3SGou Ngai 6733d4cd853Sdonjuanplatinum /// 返回 `已经打开的` 文件描述符的数量 fd_open_count(&self) -> usize6743d4cd853Sdonjuanplatinum pub fn fd_open_count(&self) -> usize { 6753d4cd853Sdonjuanplatinum let mut size = 0; 6763d4cd853Sdonjuanplatinum for fd in &self.fds { 6773d4cd853Sdonjuanplatinum if fd.is_some() { 6783d4cd853Sdonjuanplatinum size += 1; 6793d4cd853Sdonjuanplatinum } 6803d4cd853Sdonjuanplatinum } 6813d4cd853Sdonjuanplatinum return size; 6823d4cd853Sdonjuanplatinum } 6833d4cd853Sdonjuanplatinum 684004e86ffSlogin /// @brief 判断文件描述符序号是否合法 685004e86ffSlogin /// 686004e86ffSlogin /// @return true 合法 687004e86ffSlogin /// 688004e86ffSlogin /// @return false 不合法 689004e86ffSlogin #[inline] validate_fd(fd: i32) -> bool690004e86ffSlogin pub fn validate_fd(fd: i32) -> bool { 691b5b571e0SLoGin return !(fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD); 692004e86ffSlogin } 6931496ba7bSLoGin 6941496ba7bSLoGin /// 申请文件描述符,并把文件对象存入其中。 6951496ba7bSLoGin /// 6961496ba7bSLoGin /// ## 参数 6971496ba7bSLoGin /// 6981496ba7bSLoGin /// - `file` 要存放的文件对象 6991496ba7bSLoGin /// - `fd` 如果为Some(i32),表示指定要申请这个文件描述符,如果这个文件描述符已经被使用,那么返回EBADF 7001496ba7bSLoGin /// 7011496ba7bSLoGin /// ## 返回值 7021496ba7bSLoGin /// 7031496ba7bSLoGin /// - `Ok(i32)` 申请成功,返回申请到的文件描述符 7041496ba7bSLoGin /// - `Err(SystemError)` 申请失败,返回错误码,并且,file对象将被drop掉 alloc_fd(&mut self, file: File, fd: Option<i32>) -> Result<i32, SystemError>7051496ba7bSLoGin pub fn alloc_fd(&mut self, file: File, fd: Option<i32>) -> Result<i32, SystemError> { 706b5b571e0SLoGin if let Some(new_fd) = fd { 7071496ba7bSLoGin let x = &mut self.fds[new_fd as usize]; 7081496ba7bSLoGin if x.is_none() { 709dfe53cf0SGnoCiYeH *x = Some(Arc::new(file)); 7101496ba7bSLoGin return Ok(new_fd); 7111496ba7bSLoGin } else { 7121496ba7bSLoGin return Err(SystemError::EBADF); 7131496ba7bSLoGin } 7141496ba7bSLoGin } else { 7151496ba7bSLoGin // 没有指定要申请的文件描述符编号 7161496ba7bSLoGin for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 7171496ba7bSLoGin if self.fds[i].is_none() { 718dfe53cf0SGnoCiYeH self.fds[i] = Some(Arc::new(file)); 7191496ba7bSLoGin return Ok(i as i32); 7201496ba7bSLoGin } 7211496ba7bSLoGin } 7221496ba7bSLoGin return Err(SystemError::EMFILE); 7231496ba7bSLoGin } 7241496ba7bSLoGin } 7251496ba7bSLoGin 7261496ba7bSLoGin /// 根据文件描述符序号,获取文件结构体的Arc指针 7271496ba7bSLoGin /// 7281496ba7bSLoGin /// ## 参数 7291496ba7bSLoGin /// 7301496ba7bSLoGin /// - `fd` 文件描述符序号 get_file_by_fd(&self, fd: i32) -> Option<Arc<File>>731dfe53cf0SGnoCiYeH pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<File>> { 7321496ba7bSLoGin if !FileDescriptorVec::validate_fd(fd) { 7331496ba7bSLoGin return None; 7341496ba7bSLoGin } 7356046f775S裕依 self.fds[fd as usize].clone() 7361496ba7bSLoGin } 7371496ba7bSLoGin 7381496ba7bSLoGin /// 释放文件描述符,同时关闭文件。 7391496ba7bSLoGin /// 7401496ba7bSLoGin /// ## 参数 7411496ba7bSLoGin /// 7421496ba7bSLoGin /// - `fd` 文件描述符序号 drop_fd(&mut self, fd: i32) -> Result<Arc<File>, SystemError>7434afc5b7bSlinfeng pub fn drop_fd(&mut self, fd: i32) -> Result<Arc<File>, SystemError> { 74471474bc6SLoGin self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?; 7451496ba7bSLoGin 7461496ba7bSLoGin // 把文件描述符数组对应位置设置为空 7471496ba7bSLoGin let file = self.fds[fd as usize].take().unwrap(); 74834e6d6c8Syuyi2439 7494afc5b7bSlinfeng return Ok(file); 7501496ba7bSLoGin } 751876cb89eSGnoCiYeH 752bf4a4899SLoGin #[allow(dead_code)] iter(&self) -> FileDescriptorIterator753876cb89eSGnoCiYeH pub fn iter(&self) -> FileDescriptorIterator { 754876cb89eSGnoCiYeH return FileDescriptorIterator::new(self); 755876cb89eSGnoCiYeH } 756876cb89eSGnoCiYeH close_on_exec(&mut self)757876cb89eSGnoCiYeH pub fn close_on_exec(&mut self) { 758876cb89eSGnoCiYeH for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 759876cb89eSGnoCiYeH if let Some(file) = &self.fds[i] { 760dfe53cf0SGnoCiYeH let to_drop = file.close_on_exec(); 761876cb89eSGnoCiYeH if to_drop { 7624ad52e57S裕依2439 if let Err(r) = self.drop_fd(i as i32) { 7632eab6dd7S曾俊 error!( 764876cb89eSGnoCiYeH "Failed to close file: pid = {:?}, fd = {}, error = {:?}", 765876cb89eSGnoCiYeH ProcessManager::current_pcb().pid(), 766876cb89eSGnoCiYeH i, 767876cb89eSGnoCiYeH r 768876cb89eSGnoCiYeH ); 769876cb89eSGnoCiYeH } 770876cb89eSGnoCiYeH } 771876cb89eSGnoCiYeH } 772876cb89eSGnoCiYeH } 773876cb89eSGnoCiYeH } 774876cb89eSGnoCiYeH } 775876cb89eSGnoCiYeH 776876cb89eSGnoCiYeH #[derive(Debug)] 777876cb89eSGnoCiYeH pub struct FileDescriptorIterator<'a> { 778876cb89eSGnoCiYeH fds: &'a FileDescriptorVec, 779876cb89eSGnoCiYeH index: usize, 780876cb89eSGnoCiYeH } 781876cb89eSGnoCiYeH 782876cb89eSGnoCiYeH impl<'a> FileDescriptorIterator<'a> { new(fds: &'a FileDescriptorVec) -> Self783876cb89eSGnoCiYeH pub fn new(fds: &'a FileDescriptorVec) -> Self { 784876cb89eSGnoCiYeH return Self { fds, index: 0 }; 785876cb89eSGnoCiYeH } 786876cb89eSGnoCiYeH } 787876cb89eSGnoCiYeH 788876cb89eSGnoCiYeH impl<'a> Iterator for FileDescriptorIterator<'a> { 789dfe53cf0SGnoCiYeH type Item = (i32, Arc<File>); 790876cb89eSGnoCiYeH next(&mut self) -> Option<Self::Item>791876cb89eSGnoCiYeH fn next(&mut self) -> Option<Self::Item> { 792876cb89eSGnoCiYeH while self.index < FileDescriptorVec::PROCESS_MAX_FD { 793876cb89eSGnoCiYeH let fd = self.index as i32; 794876cb89eSGnoCiYeH self.index += 1; 795876cb89eSGnoCiYeH if let Some(file) = self.fds.get_file_by_fd(fd) { 796876cb89eSGnoCiYeH return Some((fd, file)); 797876cb89eSGnoCiYeH } 798876cb89eSGnoCiYeH } 799876cb89eSGnoCiYeH return None; 800876cb89eSGnoCiYeH } 801004e86ffSlogin } 802