From ce5151e47a41c745b2144a2ea97fe71fe49e2187 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Mon, 1 Jul 2024 19:27:25 -0400 Subject: [PATCH 01/39] Delegate concurrency management to file systems implementations for fine grained control --- Modules/File_system/src/Drivers/Native/mod.rs | 117 +++++++++--------- .../File_system/src/Generics/File_system.rs | 46 +++---- .../src/Generics/Virtual_file_system.rs | 79 +++++------- 3 files changed, 109 insertions(+), 133 deletions(-) diff --git a/Modules/File_system/src/Drivers/Native/mod.rs b/Modules/File_system/src/Drivers/Native/mod.rs index 8d8968d..7a48ecd 100644 --- a/Modules/File_system/src/Drivers/Native/mod.rs +++ b/Modules/File_system/src/Drivers/Native/mod.rs @@ -9,6 +9,7 @@ use std::fs::*; use std::io::{ErrorKind, Read, Seek, Write}; use std::path::PathBuf; +use std::sync::RwLock; use Task::Task_identifier_type; @@ -69,14 +70,14 @@ impl From<&Permissions_type> for std::fs::Permissions { pub struct File_system_type { Virtual_root_path: Path_owned_type, - Open_files: HashMap, + Open_files: RwLock>>, } impl File_system_type { pub fn New() -> Result { Ok(File_system_type { Virtual_root_path: Self::Get_root_path().ok_or(Error_type::Unknown)?, - Open_files: HashMap::new(), + Open_files: RwLock::new(HashMap::new()), }) } @@ -108,18 +109,18 @@ impl File_system_type { fn Get_new_file_identifier( &self, Task_identifier: Task_identifier_type, - ) -> Option { + ) -> Result { let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); let End = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); for i in Start..End { - if !self.Open_files.contains_key(&i) { - return Some(File_identifier_type::from(i as u16)); + if !self.Open_files.read()?.contains_key(&i) { + return Ok(File_identifier_type::from(i as u16)); } } - None + Err(Error_type::Too_many_open_files) } pub fn Get_full_path(&self, Path: &dyn AsRef) -> Result { @@ -141,7 +142,7 @@ impl File_system_traits for File_system_type { } fn Open( - &mut self, + &self, Task_identifier: Task_identifier_type, Path: &dyn AsRef, Flags: Flags_type, @@ -156,16 +157,15 @@ impl File_system_traits for File_system_type { .open(Full_path.as_ref() as &Path_type) .map_err(|Error| Error.kind())?; - let File_identifier = self - .Get_new_file_identifier(Task_identifier) - .ok_or(Error_type::Too_many_open_files)?; + let File_identifier = self.Get_new_file_identifier(Task_identifier)?; let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); if self .Open_files - .insert(Local_file_identifier, File) + .write()? + .insert(Local_file_identifier, RwLock::new(File)) .is_some() { return Err(Error_type::Internal_error); @@ -175,7 +175,7 @@ impl File_system_traits for File_system_type { } fn Read( - &mut self, + &self, Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Buffer: &mut [u8], @@ -183,16 +183,18 @@ impl File_system_traits for File_system_type { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); - let File = self + Ok(self .Open_files - .get_mut(&Local_file_identifier) - .ok_or(Error_type::Invalid_identifier)?; - - Ok(File.read(Buffer)?.into()) + .read()? + .get(&Local_file_identifier) + .ok_or(Error_type::Invalid_identifier)? + .write()? + .read(Buffer)? + .into()) } fn Write( - &mut self, + &self, Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Buffer: &[u8], @@ -200,26 +202,31 @@ impl File_system_traits for File_system_type { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); - let File = self + Ok(self .Open_files + .write()? .get_mut(&Local_file_identifier) - .ok_or(Error_type::Invalid_identifier)?; - - Ok(File.write(Buffer)?.into()) + .ok_or(Error_type::Invalid_identifier)? + .write()? + .write(Buffer)? + .into()) } - fn Flush(&mut self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); - let File = self - .Open_files + self.Open_files + .write()? .get_mut(&Local_file_identifier) - .ok_or(Error_type::Invalid_identifier)?; - File.flush().map_err(|Error| Error.kind().into()) + .ok_or(Error_type::Invalid_identifier)? + .write()? + .flush()?; + Ok(()) } - fn Close(&mut self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); self.Open_files + .write()? .remove(&Local_file_identifier) .ok_or(Error_type::Invalid_identifier)?; Ok(()) @@ -227,98 +234,90 @@ impl File_system_traits for File_system_type { fn Get_type(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result { let Full_path = self.Get_full_path(&Path)?; - let Metadata = metadata(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind())?; + let Metadata = metadata(Full_path.as_ref() as &Path_type)?; Ok(Metadata.file_type().into()) } fn Get_size(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result { let Full_path = self.Get_full_path(&Path)?; - let Metadata = metadata(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind())?; + let Metadata = metadata(Full_path.as_ref() as &Path_type)?; Ok(Metadata.len().into()) } fn Set_position( - &mut self, + &self, Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Position_type: &Position_type, ) -> Result { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); - let File = match self.Open_files.get_mut(&Local_file_identifier) { - Some(File) => File, - None => return Err(Error_type::Invalid_identifier), - }; - Ok(File + Ok(self + .Open_files + .write()? + .get_mut(&Local_file_identifier) + .ok_or(Error_type::Invalid_identifier)? + .write()? .seek((*Position_type).into()) - .map_err(|Error| Error_type::from(Error.kind()))? + .map_err(|Error| Error.kind())? .into()) } - fn Delete(&mut self, Path: &dyn AsRef) -> Result<()> { + fn Delete(&self, Path: &dyn AsRef) -> Result<()> { let Full_path = self.Get_full_path(&Path)?; remove_file(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind().into()) } - fn Create_directory( - &mut self, - _: Task_identifier_type, - Path: &dyn AsRef, - ) -> Result<()> { + fn Create_directory(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result<()> { let Full_path = self.Get_full_path(&Path)?; create_dir(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind().into()) } - fn Create_file(&mut self, _: Task_identifier_type, Path: &dyn AsRef) -> Result<()> { + fn Create_file(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result<()> { let Full_path = self.Get_full_path(&Path)?; OpenOptions::new() .write(true) .create_new(true) - .open(Full_path.as_ref() as &Path_type) - .map_err(|Error| Error.kind())?; + .open(Full_path.as_ref() as &Path_type)?; Ok(()) } - fn Close_all(&mut self, Task_identifier: Task_identifier_type) -> Result<()> { + fn Close_all(&self, Task_identifier: Task_identifier_type) -> Result<()> { let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); let End = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); self.Open_files + .write()? .retain(|File_identifier, _| *File_identifier < Start || *File_identifier > End); Ok(()) } fn Transfert_file_identifier( - &mut self, + &self, Old_task: Task_identifier_type, New_task: Task_identifier_type, Old_file_identifier: File_identifier_type, ) -> Result { let Old_local_file_identifier = Self::Get_local_file_identifier(Old_task, Old_file_identifier); - let New_file_identifier = self - .Get_new_file_identifier(New_task) - .ok_or(Error_type::Too_many_open_files)?; + let New_file_identifier = self.Get_new_file_identifier(New_task)?; let New_local_file_identifier = Self::Get_local_file_identifier(New_task, New_file_identifier); - let File = self - .Open_files + let mut Open_files = self.Open_files.write()?; + + let File = Open_files .remove(&Old_local_file_identifier) .ok_or(Error_type::Invalid_identifier)?; - if self - .Open_files - .insert(New_local_file_identifier, File) - .is_some() - { + if Open_files.insert(New_local_file_identifier, File).is_some() { return Err(Error_type::Internal_error); } @@ -326,7 +325,7 @@ impl File_system_traits for File_system_type { } fn Move( - &mut self, + &self, _: Task_identifier_type, Source: &dyn AsRef, Destination: &dyn AsRef, diff --git a/Modules/File_system/src/Generics/File_system.rs b/Modules/File_system/src/Generics/File_system.rs index 6c85fe7..c7eae58 100644 --- a/Modules/File_system/src/Generics/File_system.rs +++ b/Modules/File_system/src/Generics/File_system.rs @@ -8,6 +8,10 @@ use super::{ use Task::Task_identifier_type; use Users::{Group_identifier_type, User_identifier_type}; +/// File system trait. +/// +/// The management of concurrent access to the file system is delegated to the implementation. +/// Thus, implementation should use a `RwLock` or `Mutex` to manage concurrency. pub trait File_system_traits: Send + Sync { // - Status fn Exists(&self, Path: &dyn AsRef) -> Result; @@ -20,11 +24,7 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file already exists. /// Returns an error if the user / group doesn't have the permission to create the file (no write permission on parent directory). - fn Create_file( - &mut self, - Task: Task_identifier_type, - Path: &dyn AsRef, - ) -> Result<()>; + fn Create_file(&self, Task: Task_identifier_type, Path: &dyn AsRef) -> Result<()>; /// Open a file. /// @@ -32,7 +32,7 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to open the file (mode is not compatible with the file permissions). fn Open( - &mut self, + &self, Task: Task_identifier_type, Path: &dyn AsRef, Mode: Flags_type, @@ -43,14 +43,14 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file is not opened by the task (invalid file identifier). /// Returns an error if the task identifier is invalid. - fn Close(&mut self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; /// Close all files opened by the task. - fn Close_all(&mut self, Task: Task_identifier_type) -> Result<()>; + fn Close_all(&self, Task: Task_identifier_type) -> Result<()>; /// Transfer a file identifier from a task to another. fn Transfert_file_identifier( - &mut self, + &self, Old_task: Task_identifier_type, New_task: Task_identifier_type, File: File_identifier_type, @@ -61,7 +61,7 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to delete the file (no write permission on parent directory). - fn Delete(&mut self, Path: &dyn AsRef) -> Result<()>; + fn Delete(&self, Path: &dyn AsRef) -> Result<()>; // - - File operations /// Read a file. @@ -70,7 +70,7 @@ pub trait File_system_traits: Send + Sync { /// - If the file is not opened. /// - If the file is not opened in read mode. fn Read( - &mut self, + &self, Task: Task_identifier_type, File: File_identifier_type, Buffer: &mut [u8], @@ -82,14 +82,14 @@ pub trait File_system_traits: Send + Sync { /// - If the file is not opened (invalid file identifier). /// - If the file is not opened in write mode (invalid mode). fn Write( - &mut self, + &self, Task: Task_identifier_type, File: File_identifier_type, Buffer: &[u8], ) -> Result; fn Move( - &mut self, + &self, Task: Task_identifier_type, Source: &dyn AsRef, Destination: &dyn AsRef, @@ -100,12 +100,12 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// - If the file is not opened (invalid file identifier). fn Set_position( - &mut self, + &self, Task: Task_identifier_type, File: File_identifier_type, Position: &Position_type, ) -> Result; - fn Flush(&mut self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; // - Metadata // - - Size @@ -142,7 +142,7 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to change the owner (not the current owner or not the root user). fn Set_owner( - &mut self, + &self, _: Task_identifier_type, _: &dyn AsRef, _: Option, @@ -170,7 +170,7 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to set the permissions (no execute permission on parent directory). fn Set_permissions( - &mut self, + &self, _: Task_identifier_type, _: &Permissions_type, _: &dyn AsRef, @@ -200,7 +200,7 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the directory / file already exists. /// Returns an error if the user / group doesn't have the permission to create the directory (no write permission on parent directory). fn Create_directory( - &mut self, + &self, Task: Task_identifier_type, Path: &dyn AsRef, ) -> Result<()>; @@ -246,7 +246,7 @@ pub trait File_system_traits: Send + Sync { /// - Create file `read_only`, `write_only` and `read_write` in the directory /// - Ensure `not_exists` doesn't exists in the `Test_path` directory /// - Ensure `read_only`, `write_only` and `read_write` are closed - fn Test_open_close_file(&mut self) { + fn Test_open_close_file(&self) { let Task_identifier = Task_identifier_type::from(1); let Read_only = self @@ -293,7 +293,7 @@ pub trait File_system_traits: Send + Sync { /// /// - Ensure `test_dir` doesn't exists in the `Test_path` directory /// - Ensure `already_exists` exists in the `Test_path` directory - fn Test_create_directory_exists(&mut self) { + fn Test_create_directory_exists(&self) { let New_path = Get_test_path().Append("test_dir").unwrap(); let Task_identifier = Task_identifier_type::from(1); @@ -308,7 +308,7 @@ pub trait File_system_traits: Send + Sync { /// /// - Create file `read` in the `Test_path` directory containing `0123456789\n` (10 bytes) /// - Create file `empty_read` in the `Test_path` directory - fn Test_file_read(&mut self) { + fn Test_file_read(&self) { let Task_identifier = Task_identifier_type::from(1); let Read_file = Get_test_path().Append("read").unwrap(); @@ -341,7 +341,7 @@ pub trait File_system_traits: Send + Sync { /// # Before running the tests /// /// - Create file `write` in the `Test_path` directory - fn Test_file_write(&mut self) { + fn Test_file_write(&self) { let Task_identifier = Task_identifier_type::from(1); let File = Get_test_path().Append("write").unwrap(); @@ -357,7 +357,7 @@ pub trait File_system_traits: Send + Sync { } /// Run before the tests. - fn Reset_test_directory(&mut self) { + fn Reset_test_directory(&self) { let _ = self.Delete(&Get_test_path()); assert_eq!(self.Exists(&Get_test_path()), Ok(false)); diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index fe3f6f6..47b7c7c 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -1,6 +1,6 @@ use std::{ collections::HashMap, - sync::{Arc, RwLock, RwLockWriteGuard}, + sync::{Arc, RwLock}, }; use Task::Task_identifier_type; @@ -25,8 +25,7 @@ pub struct Virtual_file_system_type { /// User manager. User_manager: Users::Manager_type, /// Mounted file systems. - File_systems: - Arc>>>, + File_systems: Arc>>, /// Pipe file system Pipes_file_system: Arc>, } @@ -81,10 +80,10 @@ impl Virtual_file_system_type { let mut File_systems = self.File_systems.write()?; File_systems.insert( File_system_identifier, - RwLock::new(Internal_file_system_type { + Internal_file_system_type { Mount_point: Mount_point.as_ref().to_owned(), Inner: File_system, - }), + }, ); Ok(File_system_identifier) @@ -100,15 +99,13 @@ impl Virtual_file_system_type { } fn Get_file_system<'b>( - File_systems: &'b HashMap>, + File_systems: &'b HashMap, Path: &'b dyn AsRef, ) -> Result<(File_system_identifier_type, &'b Path_type)> { let mut Result_score = 0; let mut Result: Option<(File_system_identifier_type, &'b Path_type)> = None; for (File_system_identifier, File_system) in File_systems.iter() { - let File_system = File_system.read()?; - if let Some(Relative_path) = Path.as_ref().Strip_prefix(&File_system.Mount_point) { let Score = Relative_path.Get_length(); if Score > Result_score { @@ -138,8 +135,6 @@ impl Virtual_file_system_type { let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - let mut File_system = File_system.write()?; // Get the file system - // - Check permissions self.Check_permissions(&File_system, Task_identifier, Relative_path, Flags)?; @@ -168,7 +163,7 @@ impl Virtual_file_system_type { fn Check_permissions( &self, - File_system: &RwLockWriteGuard, + File_system: &Internal_file_system_type, Task_identifier: Task_identifier_type, Relative_path: impl AsRef, Flags: Flags_type, @@ -246,10 +241,9 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_identifier)?; // Get the file system let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -275,10 +269,9 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_identifier)?; // Get the file system File_system .Inner @@ -304,8 +297,6 @@ impl Virtual_file_system_type { .get(&File_system_identifier) .ok_or(Error_type::Invalid_identifier)?; - let mut File_system = File_system.write()?; // Get the file system - File_system .Inner .Write(Task_identifier, File_identifier, Buffer) @@ -322,10 +313,9 @@ impl Virtual_file_system_type { let (File_system_identifier, File_identifier) = File_identifier.Split(); - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_identifier)?; // Get the file system File_system .Inner @@ -343,8 +333,7 @@ impl Virtual_file_system_type { let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .read()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; // Get the file system File_system.Inner.Exists(&Relative_path) } @@ -356,8 +345,7 @@ impl Virtual_file_system_type { let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .read()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; // Get the file system let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -371,8 +359,7 @@ impl Virtual_file_system_type { let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .read()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -390,8 +377,7 @@ impl Virtual_file_system_type { let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .read()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -410,8 +396,7 @@ impl Virtual_file_system_type { let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .read()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -438,10 +423,9 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .write()?; + .ok_or(Error_type::Invalid_path)?; File_system .Inner @@ -467,8 +451,6 @@ impl Virtual_file_system_type { .get(&File_system_identifier) .ok_or(Error_type::Invalid_path)?; - let mut File_system = File_system.write()?; // Get the file system - // - Check permissions let Task_identifier = self.Task_manager.Get_current_task_identifier()?; @@ -498,7 +480,7 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems for File_system in File_systems.values() { - File_system.write()?.Inner.Close_all(Task_identifier)?; + File_system.Inner.Close_all(Task_identifier)?; } self.Pipes_file_system.write()?.Close_all(Task_identifier)?; @@ -556,10 +538,9 @@ impl Virtual_file_system_type { let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; File_system .Inner @@ -587,10 +568,9 @@ impl Virtual_file_system_type { let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; File_system .Inner @@ -609,10 +589,9 @@ impl Virtual_file_system_type { let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_path)?; // Check if the user has the right to delete the file (write permission on the parent directory) self.Check_permissions( @@ -646,7 +625,6 @@ impl Virtual_file_system_type { File_systems .get(&File_system_identifier) .ok_or(Error_type::Invalid_identifier)? - .write()? .Inner .Transfert_file_identifier(Task_identifier, New_task, File_identifier)? }; @@ -669,10 +647,9 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems - let mut File_system = File_systems + let File_system = File_systems .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)? - .write()?; // Get the file system + .ok_or(Error_type::Invalid_identifier)?; // Get the file system File_system.Inner.Flush(Task_identifier, File_identifier) } From 9adaf4936ebbda6a1ac68bd55e249c29e4936096 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Mon, 1 Jul 2024 19:53:23 -0400 Subject: [PATCH 02/39] Refactor virtual file system --- .../File_system/src/Generics/Virtual_file_system.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index 47b7c7c..027cff8 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -77,8 +77,7 @@ impl Virtual_file_system_type { return Err(Error_type::Invalid_path); } - let mut File_systems = self.File_systems.write()?; - File_systems.insert( + self.File_systems.write()?.insert( File_system_identifier, Internal_file_system_type { Mount_point: Mount_point.as_ref().to_owned(), @@ -90,8 +89,8 @@ impl Virtual_file_system_type { } pub fn Unmount(&self, File_system_identifier: File_system_identifier_type) -> Result<()> { - let mut File_systems = self.File_systems.write()?; - File_systems + self.File_systems + .write()? .remove(&File_system_identifier) .ok_or(Error_type::Invalid_identifier)?; @@ -127,8 +126,6 @@ impl Virtual_file_system_type { let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - let File_systems = self.File_systems.read()?; // Get the file systems - let File_system = File_systems .get(&File_system_identifier) .ok_or(Error_type::Invalid_path)?; @@ -137,7 +134,7 @@ impl Virtual_file_system_type { // - Check permissions - self.Check_permissions(&File_system, Task_identifier, Relative_path, Flags)?; + self.Check_permissions(File_system, Task_identifier, Relative_path, Flags)?; // - Open file @@ -595,7 +592,7 @@ impl Virtual_file_system_type { // Check if the user has the right to delete the file (write permission on the parent directory) self.Check_permissions( - &File_system, + File_system, Task_identifier, Relative_path.Go_parent().ok_or(Error_type::Invalid_path)?, Mode_type::Write_only().into(), From 707e11e9198963f6ec3256facd1d82002f81a7d3 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Mon, 1 Jul 2024 20:42:47 -0400 Subject: [PATCH 03/39] Rename Pipe_file_system_type into Manager_type and reuse it for all virtual files (device) --- .../Manager.rs} | 34 +++++++++++-------- .../Generics/{Pipe => Virtual_files}/Pipe.rs | 0 .../Generics/{Pipe => Virtual_files}/mod.rs | 4 +-- 3 files changed, 22 insertions(+), 16 deletions(-) rename Modules/File_system/src/Generics/{Pipe/File_system.rs => Virtual_files/Manager.rs} (93%) rename Modules/File_system/src/Generics/{Pipe => Virtual_files}/Pipe.rs (100%) rename Modules/File_system/src/Generics/{Pipe => Virtual_files}/mod.rs (60%) diff --git a/Modules/File_system/src/Generics/Pipe/File_system.rs b/Modules/File_system/src/Generics/Virtual_files/Manager.rs similarity index 93% rename from Modules/File_system/src/Generics/Pipe/File_system.rs rename to Modules/File_system/src/Generics/Virtual_files/Manager.rs index ea94207..57a4534 100644 --- a/Modules/File_system/src/Generics/Pipe/File_system.rs +++ b/Modules/File_system/src/Generics/Virtual_files/Manager.rs @@ -40,12 +40,12 @@ impl From for [u8; 4] { use super::Pipe_type; -pub struct Pipes_file_system_type { +pub struct Manager_type { Named_pipes: HashMap, Opened_pipes: HashMap, } -impl Pipes_file_system_type { +impl Manager_type { pub fn New() -> Self { Self { Named_pipes: HashMap::new(), @@ -294,7 +294,7 @@ mod tests { #[test] fn Test_new() { - let File_system = Pipes_file_system_type::New(); + let File_system = Manager_type::New(); assert!(File_system.Named_pipes.is_empty()); assert!(File_system.Opened_pipes.is_empty()); } @@ -304,13 +304,13 @@ mod tests { let Task_identifier = Task_identifier_type::from(1); let File_identifier = File_identifier_type::from(0); let local_file_id = - Pipes_file_system_type::Get_local_file_identifier(Task_identifier, File_identifier); + Manager_type::Get_local_file_identifier(Task_identifier, File_identifier); assert_eq!(local_file_id, 65536); // 1 << 16 | 0 } #[test] fn Test_new_unnamed_pipe() { - let mut File_system = Pipes_file_system_type::New(); + let mut File_system = Manager_type::New(); let Task_identifier = Task_identifier_type::from(1); let Size = 1024; let (Read_identifier, Write_identifier) = File_system @@ -321,17 +321,23 @@ mod tests { ) .unwrap(); assert_ne!(Read_identifier, Write_identifier); - assert!(File_system.Opened_pipes.contains_key( - &Pipes_file_system_type::Get_local_file_identifier(Task_identifier, Read_identifier) - )); - assert!(File_system.Opened_pipes.contains_key( - &Pipes_file_system_type::Get_local_file_identifier(Task_identifier, Write_identifier) - )); + assert!(File_system + .Opened_pipes + .contains_key(&Manager_type::Get_local_file_identifier( + Task_identifier, + Read_identifier + ))); + assert!(File_system + .Opened_pipes + .contains_key(&Manager_type::Get_local_file_identifier( + Task_identifier, + Write_identifier + ))); } #[test] fn Test_close_all() { - let mut File_system = Pipes_file_system_type::New(); + let mut File_system = Manager_type::New(); let Task_identifier = Task_identifier_type::from(1); let Size = 1024; File_system @@ -361,7 +367,7 @@ mod tests { #[test] fn Test_delete_named_pipe() { - let mut File_system = Pipes_file_system_type::New(); + let mut File_system = Manager_type::New(); let Size = 1024; @@ -373,7 +379,7 @@ mod tests { #[test] fn Test_read_write_unnamed_pipe() { - let mut File_system = Pipes_file_system_type::New(); + let mut File_system = Manager_type::New(); let Task_identifier = Task_identifier_type::from(1); let Size = 1024; let (Read_identifier, Write_identifier) = File_system diff --git a/Modules/File_system/src/Generics/Pipe/Pipe.rs b/Modules/File_system/src/Generics/Virtual_files/Pipe.rs similarity index 100% rename from Modules/File_system/src/Generics/Pipe/Pipe.rs rename to Modules/File_system/src/Generics/Virtual_files/Pipe.rs diff --git a/Modules/File_system/src/Generics/Pipe/mod.rs b/Modules/File_system/src/Generics/Virtual_files/mod.rs similarity index 60% rename from Modules/File_system/src/Generics/Pipe/mod.rs rename to Modules/File_system/src/Generics/Virtual_files/mod.rs index b5ee399..115d02c 100644 --- a/Modules/File_system/src/Generics/Pipe/mod.rs +++ b/Modules/File_system/src/Generics/Virtual_files/mod.rs @@ -1,6 +1,6 @@ -mod File_system; +mod Manager; #[allow(clippy::module_inception)] mod Pipe; -pub use File_system::*; +pub use Manager::*; pub use Pipe::*; From 59a1e5cdf0b732b7aa86504b78dfd9a54c2f6dc1 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Tue, 2 Jul 2024 23:28:04 -0400 Subject: [PATCH 04/39] Move pipe to its folder --- .../src/Generics/{Virtual_files => Pipe}/Manager.rs | 0 .../src/Generics/{Virtual_files => Pipe}/Pipe.rs | 0 .../File_system/src/Generics/{Virtual_files => Pipe}/mod.rs | 0 Modules/File_system/src/Generics/Virtual_file_system.rs | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename Modules/File_system/src/Generics/{Virtual_files => Pipe}/Manager.rs (100%) rename Modules/File_system/src/Generics/{Virtual_files => Pipe}/Pipe.rs (100%) rename Modules/File_system/src/Generics/{Virtual_files => Pipe}/mod.rs (100%) diff --git a/Modules/File_system/src/Generics/Virtual_files/Manager.rs b/Modules/File_system/src/Generics/Pipe/Manager.rs similarity index 100% rename from Modules/File_system/src/Generics/Virtual_files/Manager.rs rename to Modules/File_system/src/Generics/Pipe/Manager.rs diff --git a/Modules/File_system/src/Generics/Virtual_files/Pipe.rs b/Modules/File_system/src/Generics/Pipe/Pipe.rs similarity index 100% rename from Modules/File_system/src/Generics/Virtual_files/Pipe.rs rename to Modules/File_system/src/Generics/Pipe/Pipe.rs diff --git a/Modules/File_system/src/Generics/Virtual_files/mod.rs b/Modules/File_system/src/Generics/Pipe/mod.rs similarity index 100% rename from Modules/File_system/src/Generics/Virtual_files/mod.rs rename to Modules/File_system/src/Generics/Pipe/mod.rs diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index 027cff8..d7a9274 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -9,7 +9,7 @@ use Users::{Group_identifier_type, Manager_type, User_identifier_type}; use super::{ Error_type, File_system_identifier_type, File_system_traits, Flags_type, Mode_type, Path_owned_type, Path_type, Permissions_type, - Pipe::{Named_pipe_identifier_type, Pipes_file_system_type}, + Pipe::{self, Named_pipe_identifier_type}, Position_type, Result, Size_type, Status_type, Type_type, Unique_file_identifier_type, }; @@ -27,7 +27,7 @@ pub struct Virtual_file_system_type { /// Mounted file systems. File_systems: Arc>>, /// Pipe file system - Pipes_file_system: Arc>, + Pipes_file_system: Arc>, } impl Virtual_file_system_type { @@ -41,7 +41,7 @@ impl Virtual_file_system_type { Task_manager, User_manager, File_systems: Arc::new(RwLock::new(HashMap::new())), - Pipes_file_system: Arc::new(RwLock::new(Pipes_file_system_type::New())), + Pipes_file_system: Arc::new(RwLock::new(Pipe::Manager_type::New())), } } From 759a59d1cd70756cc578020593d33c962f122d18 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Tue, 2 Jul 2024 23:31:39 -0400 Subject: [PATCH 05/39] Use VecDeque for Pipe_type instead of Ring_buffer_type for Pipe --- Modules/File_system/src/Generics/Pipe/Pipe.rs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Modules/File_system/src/Generics/Pipe/Pipe.rs b/Modules/File_system/src/Generics/Pipe/Pipe.rs index 7852e15..aa13697 100644 --- a/Modules/File_system/src/Generics/Pipe/Pipe.rs +++ b/Modules/File_system/src/Generics/Pipe/Pipe.rs @@ -1,49 +1,49 @@ -use std::sync::{Arc, RwLock}; - -use Shared::Ring_buffer_type; +use std::{ + collections::VecDeque, + sync::{Arc, RwLock}, +}; use crate::Prelude::{Error_type, Result, Size_type}; /// A pipe is a FIFO (ring) buffer that can be used to communicate between tasks. #[derive(Clone)] -pub struct Pipe_type(Arc>>); +pub struct Pipe_type(Arc>>); impl Pipe_type { /// Create a new pipe with a buffer of the specified size. pub fn New(Buffer_size: usize) -> Self { - Self(Arc::new(RwLock::new(Ring_buffer_type::New(Buffer_size)))) + Self(Arc::new(RwLock::new(VecDeque::with_capacity(Buffer_size)))) } pub fn Write(&self, Data: &[u8]) -> Result<()> { let mut Inner = self.0.write()?; - if Data.len() > Inner.Get_free_space() { + if Data.len() > Inner.capacity() - Inner.len() { return Err(Error_type::File_system_full); } for Byte in Data { - if !Inner.Push(*Byte) { - return Err(Error_type::File_system_full); - } + Inner.push_back(*Byte); } + Ok(()) } pub fn Read(&self, Data: &mut [u8]) -> Result<()> { let mut Inner = self.0.write()?; - let Length = Data.len(); - if Length > Inner.Get_used_space() { + if Data.len() > Inner.len() { return Err(Error_type::File_system_full); } for Byte in Data { - *Byte = Inner.Pop().unwrap(); + *Byte = Inner.pop_front().unwrap(); } + Ok(()) } pub fn Get_size(&self) -> Result { - Ok(self.0.read()?.Get_capacity().into()) + Ok(self.0.read()?.len().into()) } } From 0b95e55d5b0e1177109afcd12d21ef5b5fb10e20 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:04:32 -0400 Subject: [PATCH 06/39] Refactor Flags_type conversion to use implicit casting --- Modules/File_system/src/Generics/Fundamentals/Flags.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Flags.rs b/Modules/File_system/src/Generics/Fundamentals/Flags.rs index 267e71c..635f652 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Flags.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Flags.rs @@ -114,6 +114,6 @@ impl From for Flags_type { impl From for u32 { fn from(Flags: Flags_type) -> Self { - Flags.0 as u32 + Flags.0 } } From c1e15770ada4b0791f09e0b25fbc785b8b637c12 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:05:33 -0400 Subject: [PATCH 07/39] Refactor Pipe.rs to use Error_type::Ressource_busy instead of Error_type::File_system_full (wrong) --- Modules/File_system/src/Generics/Pipe/Pipe.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/File_system/src/Generics/Pipe/Pipe.rs b/Modules/File_system/src/Generics/Pipe/Pipe.rs index aa13697..6c3c682 100644 --- a/Modules/File_system/src/Generics/Pipe/Pipe.rs +++ b/Modules/File_system/src/Generics/Pipe/Pipe.rs @@ -19,7 +19,7 @@ impl Pipe_type { let mut Inner = self.0.write()?; if Data.len() > Inner.capacity() - Inner.len() { - return Err(Error_type::File_system_full); + return Err(Error_type::Ressource_busy); } for Byte in Data { @@ -33,7 +33,7 @@ impl Pipe_type { let mut Inner = self.0.write()?; if Data.len() > Inner.len() { - return Err(Error_type::File_system_full); + return Err(Error_type::Ressource_busy); } for Byte in Data { From 249643b60e5510ba46e14527b7629de041b4343f Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:05:53 -0400 Subject: [PATCH 08/39] Derive Debug trait for Pipe_type --- Modules/File_system/src/Generics/Pipe/Pipe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/File_system/src/Generics/Pipe/Pipe.rs b/Modules/File_system/src/Generics/Pipe/Pipe.rs index 6c3c682..3aab5b6 100644 --- a/Modules/File_system/src/Generics/Pipe/Pipe.rs +++ b/Modules/File_system/src/Generics/Pipe/Pipe.rs @@ -6,7 +6,7 @@ use std::{ use crate::Prelude::{Error_type, Result, Size_type}; /// A pipe is a FIFO (ring) buffer that can be used to communicate between tasks. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Pipe_type(Arc>>); impl Pipe_type { From 6dc762dcdc4b1a5996e3db10ff64dea6a8641544 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:13:50 -0400 Subject: [PATCH 09/39] Use BTreeMap / BTreeSet instead of HashMap / HashSet for ordered identifier --- Modules/File_system/src/Drivers/Native/mod.rs | 8 ++++---- .../src/Generics/Virtual_file_system.rs | 9 ++------- Modules/Task/src/Manager.rs | 20 +++++++++---------- Modules/Task/src/Task.rs | 2 +- Modules/Users/src/Manager.rs | 14 ++++++------- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Modules/File_system/src/Drivers/Native/mod.rs b/Modules/File_system/src/Drivers/Native/mod.rs index 7a48ecd..bc7048e 100644 --- a/Modules/File_system/src/Drivers/Native/mod.rs +++ b/Modules/File_system/src/Drivers/Native/mod.rs @@ -3,7 +3,7 @@ use crate::Prelude::{ Permissions_type, Position_type, Result, Size_type, Type_type, }; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::env::{current_dir, var}; use std::fs::*; use std::io::{ErrorKind, Read, Seek, Write}; @@ -70,14 +70,14 @@ impl From<&Permissions_type> for std::fs::Permissions { pub struct File_system_type { Virtual_root_path: Path_owned_type, - Open_files: RwLock>>, + Open_files: RwLock>>, } impl File_system_type { pub fn New() -> Result { Ok(File_system_type { Virtual_root_path: Self::Get_root_path().ok_or(Error_type::Unknown)?, - Open_files: RwLock::new(HashMap::new()), + Open_files: RwLock::new(BTreeMap::new()), }) } @@ -109,7 +109,7 @@ impl File_system_type { fn Get_new_file_identifier( &self, Task_identifier: Task_identifier_type, - ) -> Result { + Open_files: &BTreeMap>, let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); let End = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index d7a9274..69e82bd 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -1,7 +1,4 @@ -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::BTreeMap, sync::RwLock}; use Task::Task_identifier_type; use Users::{Group_identifier_type, Manager_type, User_identifier_type}; @@ -25,9 +22,7 @@ pub struct Virtual_file_system_type { /// User manager. User_manager: Users::Manager_type, /// Mounted file systems. - File_systems: Arc>>, - /// Pipe file system - Pipes_file_system: Arc>, + File_systems: RwLock>, } impl Virtual_file_system_type { diff --git a/Modules/Task/src/Manager.rs b/Modules/Task/src/Manager.rs index 39083d2..c86738e 100644 --- a/Modules/Task/src/Manager.rs +++ b/Modules/Task/src/Manager.rs @@ -5,7 +5,7 @@ use super::*; // - - - Standard library use std::{ borrow::Cow, - collections::HashMap, + collections::{BTreeMap, HashMap}, sync::{Arc, RwLock}, }; use Users::{Root_user_identifier, User_identifier_type}; @@ -26,7 +26,7 @@ struct Task_internal_type { #[derive(Clone)] pub struct Manager_type { /// A map of all tasks managed by the manager. - Tasks: Arc>>, + Tasks: Arc>>, } impl Manager_type { @@ -39,7 +39,7 @@ impl Manager_type { Environment_variables: HashMap::new(), }; - let mut Tasks_map = HashMap::new(); + let mut Tasks_map = BTreeMap::new(); Tasks_map.insert(Task_identifier_type::from(0), Task_internal); @@ -61,7 +61,7 @@ impl Manager_type { } pub fn Get_task_name(&self, Task_identifier: Task_identifier_type) -> Result_type { - match self.Tasks.read().unwrap().get(&Task_identifier) { + match self.Tasks.read()?.get(&Task_identifier) { Some(Task) => match Task.Thread.Get_name() { Some(Name) => Ok(Name.to_string()), None => Err(Error_type::Invalid_task_identifier), @@ -143,7 +143,7 @@ impl Manager_type { &self, Task_identifier: Task_identifier_type, ) -> Result_type { - let Tasks = self.Tasks.read().unwrap(); + let Tasks = self.Tasks.read()?; Ok(Tasks .get(&Task_identifier) @@ -173,7 +173,7 @@ impl Manager_type { } pub fn Get_current_task_identifier(&self) -> Result_type { - let Tasks = self.Tasks.read().unwrap(); // Acquire lock + let Tasks = self.Tasks.read()?; for (Task_identifier, Task) in Tasks.iter() { if Task.Thread.Get_identifier() == std::thread::current().id() { @@ -196,7 +196,7 @@ impl Manager_type { Task_identifier: Task_identifier_type, Name: &str, ) -> Result_type> { - let Tasks = self.Tasks.read().unwrap(); // Acquire lock + let Tasks = self.Tasks.read()?; // Acquire lock Ok(Tasks .get(&Task_identifier) @@ -211,7 +211,7 @@ impl Manager_type { &self, Task_identifier: Task_identifier_type, ) -> Result_type, Cow<'static, str>>> { - let Tasks = self.Tasks.read().unwrap(); // Acquire lock + let Tasks = self.Tasks.read()?; // Acquire lock Ok(Tasks .get(&Task_identifier) @@ -226,7 +226,7 @@ impl Manager_type { Name: &str, Value: &str, ) -> Result_type<()> { - let mut Tasks = self.Tasks.write().unwrap(); // Acquire lock + let mut Tasks = self.Tasks.write()?; // Acquire lock Tasks .get_mut(&Task_identifier) @@ -242,7 +242,7 @@ impl Manager_type { Task_identifier: Task_identifier_type, Name: &str, ) -> Result_type<()> { - let mut Tasks = self.Tasks.write().unwrap(); // Acquire lock + let mut Tasks = self.Tasks.write()?; // Acquire lock Tasks .get_mut(&Task_identifier) diff --git a/Modules/Task/src/Task.rs b/Modules/Task/src/Task.rs index 521d778..e7e5fbe 100644 --- a/Modules/Task/src/Task.rs +++ b/Modules/Task/src/Task.rs @@ -4,7 +4,7 @@ use Users::User_identifier_type; use crate::{Join_handle_type, Manager_type, Result_type, Thread_wrapper_type}; -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] #[repr(transparent)] pub struct Task_identifier_type(u32); diff --git a/Modules/Users/src/Manager.rs b/Modules/Users/src/Manager.rs index 1063b76..e347b55 100644 --- a/Modules/Users/src/Manager.rs +++ b/Modules/Users/src/Manager.rs @@ -1,6 +1,6 @@ use super::*; use std::{ - collections::{HashMap, HashSet}, + collections::{BTreeMap, BTreeSet}, sync::{Arc, RwLock}, vec::Vec, }; @@ -11,12 +11,12 @@ struct Internal_user_type { struct Internal_group_type { pub Name: String, - pub Users: HashSet, + pub Users: BTreeSet, } struct Internal_manager_type { - pub Users: HashMap, - pub Groups: HashMap, + pub Users: BTreeMap, + pub Groups: BTreeMap, } #[derive(Clone)] @@ -25,8 +25,8 @@ pub struct Manager_type(Arc>); impl Manager_type { pub fn New() -> Self { Self(Arc::new(RwLock::new(Internal_manager_type { - Users: HashMap::new(), - Groups: HashMap::new(), + Users: BTreeMap::new(), + Groups: BTreeMap::new(), }))) } @@ -78,7 +78,7 @@ impl Manager_type { let Group = Internal_group_type { Name: Name.to_string(), - Users: HashSet::new(), + Users: BTreeSet::new(), }; if self.Exists_group(Identifier)? { From d31fe9c55284e1f447989f94f80e7c63b6d3cdf2 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:17:37 -0400 Subject: [PATCH 10/39] Add Is_empty and Is_canonical to Path_reference_type --- .../src/Generics/Fundamentals/Path/Path_reference.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs b/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs index d59f747..119283e 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs @@ -46,6 +46,14 @@ impl Path_type { &self.0 == "/" } + pub fn Is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn Is_canonical(&self) -> bool { + self.0.chars().all(|c| c != '.') + } + pub fn Go_parent(&self) -> Option<&Path_type> { let Characters_to_remove = match self.0.rfind(Separator) { Some(index) => index, From f34828b5e5d4ce9bbe064dd716e7ac9753f811bc Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:18:31 -0400 Subject: [PATCH 11/39] Differentiate absolute and relative path stripping --- .../Fundamentals/Path/Path_reference.rs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs b/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs index 119283e..440f6ab 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Path/Path_reference.rs @@ -128,12 +128,22 @@ impl Path_type { let mut Stripped_prefix = self.0.strip_prefix(&Path_prefix.0)?; if Stripped_prefix.starts_with(Separator) { - Stripped_prefix = &Stripped_prefix[1..]; + Stripped_prefix = &Stripped_prefix[1..] } Self::New(Stripped_prefix) } + pub fn Strip_prefix_absolute<'b>(&'b self, Path_prefix: &Path_type) -> Option<&'b Path_type> { + if Path_prefix.Is_root() { + return Some(self); + } + + let Stripped_prefix = self.0.strip_prefix(&Path_prefix.0)?; + + Self::New(Stripped_prefix) + } + pub fn Strip_suffix<'b>(&'b self, Path_suffix: &Path_type) -> Option<&'b Path_type> { Self::New(self.0.strip_suffix(&Path_suffix.0)?) } @@ -206,10 +216,37 @@ mod Tests { let Prefix = Path_type::New("/home/user").unwrap(); assert_eq!(Path.Strip_prefix(Prefix).unwrap().As_str(), "file.txt"); + let Path = Path_type::New("/home/user/file.txt").unwrap(); + let Prefix = Path_type::New("/").unwrap(); + assert_eq!( + Path.Strip_prefix(Prefix).unwrap().As_str(), + "home/user/file.txt" + ); + let Invalid_prefix = Path_type::New("/home/invalid/").unwrap(); assert_eq!(Path.Strip_prefix(Invalid_prefix), None); } + #[test] + fn Test_strip_prefix_absolute() { + let Path = Path_type::New("/home/user/file.txt").unwrap(); + let Prefix = Path_type::New("/home/user").unwrap(); + assert_eq!( + Path.Strip_prefix_absolute(Prefix).unwrap().As_str(), + "/file.txt" + ); + + let Path = Path_type::New("/home/user/file.txt").unwrap(); + let Prefix = Path_type::New("/").unwrap(); + assert_eq!( + Path.Strip_prefix_absolute(Prefix).unwrap().As_str(), + "/home/user/file.txt" + ); + + let Invalid_prefix = Path_type::New("/home/invalid/").unwrap(); + assert_eq!(Path.Strip_prefix_absolute(Invalid_prefix), None); + } + #[test] fn Test_strip_suffix() { let Path = Path_type::New("/home/user/file.txt").unwrap(); From 74faa8a239eb6f51b9753330ecac25b2b1f42bb9 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:19:38 -0400 Subject: [PATCH 12/39] Path_owned_type is now transparent and derive Hash and PartialEq --- .../File_system/src/Generics/Fundamentals/Path/Path_owned.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs b/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs index c9d756c..9e57beb 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs @@ -5,7 +5,8 @@ use std::{ use super::{Extension_separator, Path_type, Separator}; -#[derive(Clone, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +#[repr(transparent)] pub struct Path_owned_type(String); impl Path_owned_type { From 5974c7979535c14813d1213e8bffb1148e6e9913 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:20:05 -0400 Subject: [PATCH 13/39] An empty path is now considered valid --- .../Generics/Fundamentals/Path/Path_owned.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs b/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs index 9e57beb..e5ae746 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Path/Path_owned.rs @@ -39,6 +39,10 @@ impl Path_owned_type { return None; } + if Path.as_ref().Is_empty() { + return Some(self); + } + if !self.0.ends_with(Separator) { self.0.push(Separator); } @@ -125,11 +129,6 @@ impl Path_owned_type { pub fn Is_valid_string(String: &str) -> bool { let Invalid = ['\0', ':', '*', '?', '"', '<', '>', '|', ' ']; - if String.is_empty() { - // Empty string is not valid. - return false; - } - for Character in String.chars() { // Check if the string contains invalid characters. if Invalid.contains(&Character) { @@ -181,12 +180,6 @@ impl AsRef for Path_owned_type { } } -impl PartialEq for Path_owned_type { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - impl Deref for Path_owned_type { type Target = Path_type; @@ -230,7 +223,7 @@ mod tests { assert!(!Is_valid_string("Hello/World.txt|")); assert!(!Is_valid_string("Hello/World.txt ")); assert!(!Is_valid_string("Hello/World.txt\0")); - assert!(!Is_valid_string("")); + assert!(Is_valid_string("")); assert!(!Is_valid_string("Hello/Wo rld.txt/")); } From 2020c6e74f153c1c9ad833a0a8c870e14e3a6573 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:21:43 -0400 Subject: [PATCH 14/39] Refactor File_system_identifier_type to use u16 instead of u8 --- .../src/Generics/Fundamentals/Identifiers.rs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs b/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs index c92fc1d..5832aa3 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs @@ -18,39 +18,35 @@ impl From for u16 { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(transparent)] -pub struct File_system_identifier_type(u8); +pub struct File_system_identifier_type(u16); impl File_system_identifier_type { - pub fn New() -> Self { - Self(0) - } - - pub const fn New_from(Identifier: u8) -> Self { + pub const fn New(Identifier: u16) -> Self { Self(Identifier) } } -impl AddAssign for File_system_identifier_type { - fn add_assign(&mut self, rhs: u8) { +impl AddAssign for File_system_identifier_type { + fn add_assign(&mut self, rhs: u16) { self.0 += rhs; } } -impl Add for File_system_identifier_type { +impl Add for File_system_identifier_type { type Output = Self; - fn add(self, rhs: u8) -> Self::Output { + fn add(self, rhs: u16) -> Self::Output { Self(self.0 + rhs) } } -impl From for File_system_identifier_type { - fn from(Internal_file_system_identifier: u8) -> Self { +impl From for File_system_identifier_type { + fn from(Internal_file_system_identifier: u16) -> Self { File_system_identifier_type(Internal_file_system_identifier) } } -impl From for u8 { +impl From for u16 { fn from(Internal_file_system_identifier: File_system_identifier_type) -> Self { Internal_file_system_identifier.0 } @@ -69,7 +65,7 @@ impl Unique_file_identifier_type { } pub fn Split(self) -> (File_system_identifier_type, File_identifier_type) { - let File_system_identifier = File_system_identifier_type::New_from((self.0 >> 16) as u8); + let File_system_identifier = File_system_identifier_type::New((self.0 >> 16) as u16); let File_identifier = File_identifier_type((self.0 & 0xFFFF) as u16); (File_system_identifier, File_identifier) } From 582ebda6825fe58317ee7f7857195ea5de9abed9 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:22:32 -0400 Subject: [PATCH 15/39] Derive Ord and PartialOrd for File system identifier types that are used in BTreeMap --- .../File_system/src/Generics/Fundamentals/Identifiers.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs b/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs index 5832aa3..f6f318b 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Identifiers.rs @@ -1,6 +1,6 @@ use std::ops::{Add, AddAssign}; -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] #[repr(transparent)] pub struct File_identifier_type(u16); @@ -16,7 +16,7 @@ impl From for u16 { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] #[repr(transparent)] pub struct File_system_identifier_type(u16); @@ -52,7 +52,7 @@ impl From for u16 { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] #[repr(transparent)] pub struct Unique_file_identifier_type(u32); From 2ec9cadbae265392a7aa313319158a61036cc6f5 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:23:31 -0400 Subject: [PATCH 16/39] Permission_type and Permissions_type now use u16, are transparent and Derive copy trait --- Modules/File_system/src/Generics/Fundamentals/Permission.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/File_system/src/Generics/Fundamentals/Permission.rs b/Modules/File_system/src/Generics/Fundamentals/Permission.rs index ef906f2..1bb49c6 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Permission.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Permission.rs @@ -1,4 +1,5 @@ -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] pub struct Permissions_type(u16); impl Permissions_type { @@ -100,7 +101,8 @@ impl Permissions_type { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] pub struct Permission_type(u8); impl Permission_type { From 1efda40dcc31e18350913458cdf100cc7b01d1b5 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:23:59 -0400 Subject: [PATCH 17/39] Add New_write_execute and New_read_execute for Permission_type --- .../File_system/src/Generics/Fundamentals/Permission.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Modules/File_system/src/Generics/Fundamentals/Permission.rs b/Modules/File_system/src/Generics/Fundamentals/Permission.rs index 1bb49c6..a890a9f 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Permission.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Permission.rs @@ -126,6 +126,14 @@ impl Permission_type { Self::New(false, false, true) } + pub fn New_write_execute() -> Self { + Self::New(false, true, true) + } + + pub fn New_read_execute() -> Self { + Self::New(true, false, true) + } + /// Creates a new permission with full access (equivalent to Unix permission 7). pub fn New_full() -> Self { Self::New(true, true, true) From 2cfc6320e0dd51429e057b2dcce4c9e659c6207e Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:24:29 -0400 Subject: [PATCH 18/39] Add Include() for Permission_type --- .../src/Generics/Fundamentals/Permission.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/Modules/File_system/src/Generics/Fundamentals/Permission.rs b/Modules/File_system/src/Generics/Fundamentals/Permission.rs index a890a9f..d4c563b 100644 --- a/Modules/File_system/src/Generics/Fundamentals/Permission.rs +++ b/Modules/File_system/src/Generics/Fundamentals/Permission.rs @@ -187,6 +187,10 @@ impl Permission_type { self.0 } + pub fn Include(&self, Other: Self) -> bool { + (self.0 & Other.0) == Other.0 + } + /// Creates a permission from a Unix permission. pub fn From_unix(Unix: u8) -> Option { if Unix > 0b111 { @@ -266,4 +270,88 @@ mod Tests { let Permissions = Permissions_type::New(&User, &Group, &Others); assert_eq!(Permissions.To_unix(), 0b101_110_011); } + + #[test] + fn Test_permission_type_include() { + let Read = Permission_type::New_read(); + let Write = Permission_type::New_write(); + let Read_write = Permission_type::New_read_write(); + let Read_execute = Permission_type::New_read_execute(); + let Write_execute = Permission_type::New_write_execute(); + let Execute = Permission_type::New_execute(); + let Full = Permission_type::New_full(); + let No = Permission_type::New_none(); + + assert!(Full.Include(Read)); + assert!(Full.Include(Write)); + assert!(Full.Include(Execute)); + assert!(Full.Include(Read_write)); + assert!(Full.Include(Read_execute)); + assert!(Full.Include(Write_execute)); + assert!(Full.Include(Full)); + assert!(Full.Include(No)); + + assert!(Read.Include(Read)); + assert!(!Read.Include(Write)); + assert!(!Read.Include(Execute)); + assert!(!Read.Include(Read_write)); + assert!(!Read.Include(Read_execute)); + assert!(!Read.Include(Write_execute)); + assert!(!Read.Include(Full)); + assert!(Read.Include(No)); + + assert!(!Write.Include(Read)); + assert!(Write.Include(Write)); + assert!(!Write.Include(Execute)); + assert!(!Write.Include(Read_write)); + assert!(!Write.Include(Read_execute)); + assert!(!Write.Include(Write_execute)); + assert!(!Write.Include(Full)); + assert!(Write.Include(No)); + + assert!(!Execute.Include(Read)); + assert!(!Execute.Include(Write)); + assert!(Execute.Include(Execute)); + assert!(!Execute.Include(Read_write)); + assert!(!Execute.Include(Read_execute)); + assert!(!Execute.Include(Write_execute)); + assert!(!Execute.Include(Full)); + assert!(Execute.Include(No)); + + assert!(Read_write.Include(Read)); + assert!(Read_write.Include(Write)); + assert!(!Read_write.Include(Execute)); + assert!(Read_write.Include(Read_write)); + assert!(!Read_write.Include(Read_execute)); + assert!(!Read_write.Include(Write_execute)); + assert!(!Read_write.Include(Full)); + assert!(Read_write.Include(No)); + + assert!(Read_execute.Include(Read)); + assert!(!Read_execute.Include(Write)); + assert!(Read_execute.Include(Execute)); + assert!(!Read_execute.Include(Read_write)); + assert!(Read_execute.Include(Read_execute)); + assert!(!Read_execute.Include(Write_execute)); + assert!(!Read_execute.Include(Full)); + assert!(Read_execute.Include(No)); + + assert!(!Write_execute.Include(Read)); + assert!(Write_execute.Include(Write)); + assert!(Write_execute.Include(Execute)); + assert!(!Write_execute.Include(Read_write)); + assert!(!Write_execute.Include(Read_execute)); + assert!(Write_execute.Include(Write_execute)); + assert!(!Write_execute.Include(Full)); + assert!(Write_execute.Include(No)); + + assert!(!No.Include(Read)); + assert!(!No.Include(Write)); + assert!(!No.Include(Execute)); + assert!(!No.Include(Read_write)); + assert!(!No.Include(Read_execute)); + assert!(!No.Include(Write_execute)); + assert!(!No.Include(Full)); + assert!(No.Include(No)); + } } From f598388ea34684bfee140397f57669c5fbec7026 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:32:04 -0400 Subject: [PATCH 19/39] Rename Result<> to Result_type<> --- Modules/File_system/src/Drivers/Native/mod.rs | 41 +++++++------ Modules/File_system/src/Generics/Error.rs | 2 +- Modules/File_system/src/Generics/File.rs | 16 ++--- .../File_system/src/Generics/File_system.rs | 56 +++++++---------- Modules/File_system/src/Generics/Pipe/Pipe.rs | 8 +-- .../src/Generics/Virtual_file_system.rs | 60 +++++-------------- 6 files changed, 68 insertions(+), 115 deletions(-) diff --git a/Modules/File_system/src/Drivers/Native/mod.rs b/Modules/File_system/src/Drivers/Native/mod.rs index bc7048e..d982d2e 100644 --- a/Modules/File_system/src/Drivers/Native/mod.rs +++ b/Modules/File_system/src/Drivers/Native/mod.rs @@ -1,6 +1,6 @@ use crate::Prelude::{ Error_type, File_identifier_type, File_system_traits, Flags_type, Path_owned_type, Path_type, - Permissions_type, Position_type, Result, Size_type, Type_type, + Permissions_type, Position_type, Result_type, Size_type, Type_type, }; use std::collections::BTreeMap; @@ -74,7 +74,7 @@ pub struct File_system_type { } impl File_system_type { - pub fn New() -> Result { + pub fn New() -> Result_type { Ok(File_system_type { Virtual_root_path: Self::Get_root_path().ok_or(Error_type::Unknown)?, Open_files: RwLock::new(BTreeMap::new()), @@ -107,15 +107,15 @@ impl File_system_type { } fn Get_new_file_identifier( - &self, Task_identifier: Task_identifier_type, Open_files: &BTreeMap>, + ) -> Result_type { let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); let End = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); for i in Start..End { - if !self.Open_files.read()?.contains_key(&i) { + if !Open_files.contains_key(&i) { return Ok(File_identifier_type::from(i as u16)); } } @@ -123,7 +123,7 @@ impl File_system_type { Err(Error_type::Too_many_open_files) } - pub fn Get_full_path(&self, Path: &dyn AsRef) -> Result { + pub fn Get_full_path(&self, Path: &dyn AsRef) -> Result_type { self.Virtual_root_path .clone() .Join(Path) @@ -132,7 +132,7 @@ impl File_system_type { } impl File_system_traits for File_system_type { - fn Exists(&self, Path: &dyn AsRef) -> Result { + fn Exists(&self, Path: &dyn AsRef) -> Result_type { metadata(self.Get_full_path(&Path)?.as_ref() as &Path_type) .map(|_| true) .or_else(|Error| match Error.kind() { @@ -146,7 +146,7 @@ impl File_system_traits for File_system_type { Task_identifier: Task_identifier_type, Path: &dyn AsRef, Flags: Flags_type, - ) -> Result { + ) -> Result_type { let Full_path = self.Get_full_path(&Path)?; let mut Open_options = OpenOptions::new(); @@ -179,7 +179,7 @@ impl File_system_traits for File_system_type { Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Buffer: &mut [u8], - ) -> Result { + ) -> Result_type { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); @@ -198,7 +198,7 @@ impl File_system_traits for File_system_type { Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Buffer: &[u8], - ) -> Result { + ) -> Result_type { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); @@ -212,7 +212,7 @@ impl File_system_traits for File_system_type { .into()) } - fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()> { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); self.Open_files .write()? @@ -223,7 +223,7 @@ impl File_system_traits for File_system_type { Ok(()) } - fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()> { + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()> { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); self.Open_files .write()? @@ -232,13 +232,13 @@ impl File_system_traits for File_system_type { Ok(()) } - fn Get_type(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result { + fn Get_type(&self, Path: &dyn AsRef) -> Result_type { let Full_path = self.Get_full_path(&Path)?; let Metadata = metadata(Full_path.as_ref() as &Path_type)?; Ok(Metadata.file_type().into()) } - fn Get_size(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result { + fn Get_size(&self, Path: &dyn AsRef) -> Result_type { let Full_path = self.Get_full_path(&Path)?; let Metadata = metadata(Full_path.as_ref() as &Path_type)?; Ok(Metadata.len().into()) @@ -249,7 +249,7 @@ impl File_system_traits for File_system_type { Task_identifier: Task_identifier_type, File_identifier: File_identifier_type, Position_type: &Position_type, - ) -> Result { + ) -> Result_type { let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); @@ -264,19 +264,19 @@ impl File_system_traits for File_system_type { .into()) } - fn Delete(&self, Path: &dyn AsRef) -> Result<()> { + fn Delete(&self, Path: &dyn AsRef) -> Result_type<()> { let Full_path = self.Get_full_path(&Path)?; remove_file(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind().into()) } - fn Create_directory(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result<()> { + fn Create_directory(&self, Path: &dyn AsRef) -> Result_type<()> { let Full_path = self.Get_full_path(&Path)?; create_dir(Full_path.as_ref() as &Path_type).map_err(|Error| Error.kind().into()) } - fn Create_file(&self, _: Task_identifier_type, Path: &dyn AsRef) -> Result<()> { + fn Create_file(&self, Path: &dyn AsRef) -> Result_type<()> { let Full_path = self.Get_full_path(&Path)?; OpenOptions::new() @@ -287,7 +287,7 @@ impl File_system_traits for File_system_type { Ok(()) } - fn Close_all(&self, Task_identifier: Task_identifier_type) -> Result<()> { + fn Close_all(&self, Task_identifier: Task_identifier_type) -> Result_type<()> { let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); let End = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); @@ -304,7 +304,7 @@ impl File_system_traits for File_system_type { Old_task: Task_identifier_type, New_task: Task_identifier_type, Old_file_identifier: File_identifier_type, - ) -> Result { + ) -> Result_type { let Old_local_file_identifier = Self::Get_local_file_identifier(Old_task, Old_file_identifier); let New_file_identifier = self.Get_new_file_identifier(New_task)?; @@ -326,10 +326,9 @@ impl File_system_traits for File_system_type { fn Move( &self, - _: Task_identifier_type, Source: &dyn AsRef, Destination: &dyn AsRef, - ) -> Result<()> { + ) -> Result_type<()> { let Source = self.Get_full_path(Source)?; let Destination = self.Get_full_path(Destination)?; diff --git a/Modules/File_system/src/Generics/Error.rs b/Modules/File_system/src/Generics/Error.rs index a5462c8..07fc3cf 100644 --- a/Modules/File_system/src/Generics/Error.rs +++ b/Modules/File_system/src/Generics/Error.rs @@ -1,6 +1,6 @@ use std::{num::NonZeroU32, sync::PoisonError}; -pub type Result = std::result::Result; +pub type Result_type = std::result::Result; #[derive(Debug, PartialEq, Clone, Copy)] #[repr(C)] diff --git a/Modules/File_system/src/Generics/File.rs b/Modules/File_system/src/Generics/File.rs index 674ae22..c123717 100644 --- a/Modules/File_system/src/Generics/File.rs +++ b/Modules/File_system/src/Generics/File.rs @@ -1,5 +1,5 @@ use super::{ - Flags_type, Path_type, Position_type, Result, Size_type, Status_type, + Flags_type, Path_type, Position_type, Result_type, Size_type, Status_type, Unique_file_identifier_type, Virtual_file_system::Virtual_file_system_type, }; @@ -24,7 +24,7 @@ impl File_type { File_system: &Virtual_file_system_type, Path: impl AsRef, Flags: Flags_type, - ) -> Result { + ) -> Result_type { let File_identifier = File_system.Open(Path, Flags)?; Ok(File_type { @@ -37,7 +37,7 @@ impl File_type { File_system: &Virtual_file_system_type, Size: usize, Status: Status_type, - ) -> Result<(Self, Self)> { + ) -> Result_type<(Self, Self)> { let (File_identifier_read, File_identifier_write) = File_system.Create_unnamed_pipe(Size, Status)?; @@ -54,7 +54,7 @@ impl File_type { } // - Setters - pub fn Set_position(&self, Position: &Position_type) -> Result { + pub fn Set_position(&self, Position: &Position_type) -> Result_type { self.File_system .Set_position(self.Get_file_identifier(), Position) } @@ -66,19 +66,19 @@ impl File_type { // - Operations - pub fn Write(&self, Buffer: &[u8]) -> Result { + pub fn Write(&self, Buffer: &[u8]) -> Result_type { self.File_system.Write(self.Get_file_identifier(), Buffer) } - pub fn Write_line(&self, Buffer: &[u8]) -> Result { + pub fn Write_line(&self, Buffer: &[u8]) -> Result_type { let Size = self.Write(Buffer)? + self.Write(b"\n")?; Ok(Size) } - pub fn Read(&self, Buffer: &mut [u8]) -> Result { + pub fn Read(&self, Buffer: &mut [u8]) -> Result_type { self.File_system.Read(self.Get_file_identifier(), Buffer) } - pub fn Read_line(&self, Buffer: &mut [u8]) -> Result<()> { + pub fn Read_line(&self, Buffer: &mut [u8]) -> Result_type<()> { let mut Index = 0; loop { let Size: usize = self.Read(&mut Buffer[Index..Index + 1])?.into(); diff --git a/Modules/File_system/src/Generics/File_system.rs b/Modules/File_system/src/Generics/File_system.rs index c7eae58..83ee73a 100644 --- a/Modules/File_system/src/Generics/File_system.rs +++ b/Modules/File_system/src/Generics/File_system.rs @@ -14,7 +14,7 @@ use Users::{Group_identifier_type, User_identifier_type}; /// Thus, implementation should use a `RwLock` or `Mutex` to manage concurrency. pub trait File_system_traits: Send + Sync { // - Status - fn Exists(&self, Path: &dyn AsRef) -> Result; + fn Exists(&self, Path: &dyn AsRef) -> Result_type; // - Manipulation // - - Open/close/delete @@ -24,7 +24,7 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file already exists. /// Returns an error if the user / group doesn't have the permission to create the file (no write permission on parent directory). - fn Create_file(&self, Task: Task_identifier_type, Path: &dyn AsRef) -> Result<()>; + fn Create_file(&self, Path: &dyn AsRef) -> Result_type<()>; /// Open a file. /// @@ -36,17 +36,17 @@ pub trait File_system_traits: Send + Sync { Task: Task_identifier_type, Path: &dyn AsRef, Mode: Flags_type, - ) -> Result; + ) -> Result_type; /// Close a file. /// /// # Errors /// Returns an error if the file is not opened by the task (invalid file identifier). /// Returns an error if the task identifier is invalid. - fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()>; /// Close all files opened by the task. - fn Close_all(&self, Task: Task_identifier_type) -> Result<()>; + fn Close_all(&self, Task: Task_identifier_type) -> Result_type<()>; /// Transfer a file identifier from a task to another. fn Transfert_file_identifier( @@ -54,14 +54,14 @@ pub trait File_system_traits: Send + Sync { Old_task: Task_identifier_type, New_task: Task_identifier_type, File: File_identifier_type, - ) -> Result; + ) -> Result_type; /// Delete a file. /// /// # Errors /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to delete the file (no write permission on parent directory). - fn Delete(&self, Path: &dyn AsRef) -> Result<()>; + fn Delete(&self, Path: &dyn AsRef) -> Result_type<()>; // - - File operations /// Read a file. @@ -74,7 +74,7 @@ pub trait File_system_traits: Send + Sync { Task: Task_identifier_type, File: File_identifier_type, Buffer: &mut [u8], - ) -> Result; + ) -> Result_type; /// Write a file. /// @@ -86,14 +86,14 @@ pub trait File_system_traits: Send + Sync { Task: Task_identifier_type, File: File_identifier_type, Buffer: &[u8], - ) -> Result; + ) -> Result_type; fn Move( &self, Task: Task_identifier_type, Source: &dyn AsRef, Destination: &dyn AsRef, - ) -> Result<()>; + ) -> Result_type<()>; /// Set the position of the file. /// @@ -104,8 +104,9 @@ pub trait File_system_traits: Send + Sync { Task: Task_identifier_type, File: File_identifier_type, Position: &Position_type, - ) -> Result; - fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result<()>; + ) -> Result_type; + + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()>; // - Metadata // - - Size @@ -114,22 +115,14 @@ pub trait File_system_traits: Send + Sync { /// /// # Errors /// - If the file doesn't exists. - fn Get_type( - &self, - Task: Task_identifier_type, - Path_type: &dyn AsRef, - ) -> Result; + fn Get_type(&self, Path_type: &dyn AsRef) -> Result_type; /// Get the size of the file. /// /// # Errors /// - If the file doesn't exists. /// - If the user / group doesn't have the permission to get the size (no execute permission on parent directory). - fn Get_size( - &self, - Task: Task_identifier_type, - Path: &dyn AsRef, - ) -> Result; + fn Get_size(&self, Path: &dyn AsRef) -> Result_type; // - - Security @@ -147,7 +140,7 @@ pub trait File_system_traits: Send + Sync { _: &dyn AsRef, _: Option, _: Option, - ) -> Result<()> { + ) -> Result_type<()> { Ok(()) // TODO : Implement with permission file } @@ -160,7 +153,7 @@ pub trait File_system_traits: Send + Sync { &self, _: Task_identifier_type, _: &dyn AsRef, - ) -> Result<(User_identifier_type, Group_identifier_type)> { + ) -> Result_type<(User_identifier_type, Group_identifier_type)> { Ok((0, 0)) // TODO : Implement with permission file } @@ -169,12 +162,7 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to set the permissions (no execute permission on parent directory). - fn Set_permissions( - &self, - _: Task_identifier_type, - _: &Permissions_type, - _: &dyn AsRef, - ) -> Result<()> { + fn Set_permissions(&self, _: &dyn AsRef, _: Permissions_type) -> Result_type<()> { Ok(()) // TODO : Implement with permission file } @@ -183,11 +171,7 @@ pub trait File_system_traits: Send + Sync { /// # Errors /// Returns an error if the file doesn't exists. /// Returns an error if the user / group doesn't have the permission to get the permissions (no execute permission on parent directory). - fn Get_permissions( - &self, - _: Task_identifier_type, - _: &dyn AsRef, - ) -> Result { + fn Get_permissions(&self, _: &dyn AsRef) -> Result_type { Ok(Permissions_type::New_all_full()) // TODO : Implement with permission file } @@ -199,7 +183,7 @@ pub trait File_system_traits: Send + Sync { /// /// Returns an error if the directory / file already exists. /// Returns an error if the user / group doesn't have the permission to create the directory (no write permission on parent directory). - fn Create_directory( + fn Create_directory(&self, Path: &dyn AsRef) -> Result_type<()>; &self, Task: Task_identifier_type, Path: &dyn AsRef, diff --git a/Modules/File_system/src/Generics/Pipe/Pipe.rs b/Modules/File_system/src/Generics/Pipe/Pipe.rs index 3aab5b6..2f9abda 100644 --- a/Modules/File_system/src/Generics/Pipe/Pipe.rs +++ b/Modules/File_system/src/Generics/Pipe/Pipe.rs @@ -3,7 +3,7 @@ use std::{ sync::{Arc, RwLock}, }; -use crate::Prelude::{Error_type, Result, Size_type}; +use crate::Prelude::{Error_type, Result_type, Size_type}; /// A pipe is a FIFO (ring) buffer that can be used to communicate between tasks. #[derive(Clone, Debug)] @@ -15,7 +15,7 @@ impl Pipe_type { Self(Arc::new(RwLock::new(VecDeque::with_capacity(Buffer_size)))) } - pub fn Write(&self, Data: &[u8]) -> Result<()> { + pub fn Write(&self, Data: &[u8]) -> Result_type<()> { let mut Inner = self.0.write()?; if Data.len() > Inner.capacity() - Inner.len() { @@ -29,7 +29,7 @@ impl Pipe_type { Ok(()) } - pub fn Read(&self, Data: &mut [u8]) -> Result<()> { + pub fn Read(&self, Data: &mut [u8]) -> Result_type<()> { let mut Inner = self.0.write()?; if Data.len() > Inner.len() { @@ -43,7 +43,7 @@ impl Pipe_type { Ok(()) } - pub fn Get_size(&self) -> Result { + pub fn Get_size(&self) -> Result_type { Ok(self.0.read()?.len().into()) } } diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index 69e82bd..5170bf9 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -59,8 +59,7 @@ impl Virtual_file_system_type { &self, File_system: Box, Mount_point: impl AsRef, - ) -> Result { - if self.Exists(Mount_point.as_ref())? { + ) -> Result_type { return Err(Error_type::Already_exists); } @@ -83,8 +82,7 @@ impl Virtual_file_system_type { Ok(File_system_identifier) } - pub fn Unmount(&self, File_system_identifier: File_system_identifier_type) -> Result<()> { - self.File_systems + ) -> Result_type> { .write()? .remove(&File_system_identifier) .ok_or(Error_type::Invalid_identifier)?; @@ -187,41 +185,7 @@ impl Virtual_file_system_type { Ok(()) } - fn Open_named_pipe( - &self, - Relative_path: impl AsRef, - Flags: Flags_type, - ) -> Result { - let Path = Relative_path - .as_ref() - .Set_extension(Self::Named_pipe_extension) - .ok_or(Error_type::Invalid_path)?; // Append the pipe extension - - let File = self.Open(Path, Mode_type::Read_only().into())?; // Open the file - - let mut Pipe_identifier = [0; 4]; - - let Bytes_read = self.Read(File, &mut Pipe_identifier)?; - - if Bytes_read != Pipe_identifier.len() { - return Err(Error_type::Invalid_path); - } - - let Pipe_identifier = Named_pipe_identifier_type::from(Pipe_identifier); - - let File_identifier = self.Pipes_file_system.write()?.Open( - self.Task_manager.Get_current_task_identifier()?, - Pipe_identifier, - Flags, - )?; - - Ok(Unique_file_identifier_type::New( - Self::Pipe_file_system_identifier, - File_identifier, - )) - } - - pub fn Close(&self, File: Unique_file_identifier_type) -> Result<()> { + pub fn Close(&self, File: Unique_file_identifier_type) -> Result_type<()> { let (File_system_identifier, File_identifier) = File.Split(); if File_system_identifier == Self::Pipe_file_system_identifier { @@ -246,7 +210,7 @@ impl Virtual_file_system_type { &self, File_identifier: Unique_file_identifier_type, Buffer: &mut [u8], - ) -> Result { + ) -> Result_type { let (File_system_identifier, File_identifier) = File_identifier.Split(); if File_system_identifier == Self::Pipe_file_system_identifier { @@ -270,7 +234,11 @@ impl Virtual_file_system_type { .Read(Task_identifier, File_identifier, Buffer) } - pub fn Write(&self, File: Unique_file_identifier_type, Buffer: &[u8]) -> Result { + pub fn Write( + &self, + File: Unique_file_identifier_type, + Buffer: &[u8], + ) -> Result_type { let (File_system_identifier, File_identifier) = File.Split(); if File_system_identifier == Self::Pipe_file_system_identifier { @@ -298,7 +266,9 @@ impl Virtual_file_system_type { &self, File_identifier: Unique_file_identifier_type, Position: &Position_type, - ) -> Result { + ) -> Result_type { + let (File_system_identifier, File_identifier) = File_identifier.Split(); + let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems @@ -569,7 +539,7 @@ impl Virtual_file_system_type { .Create_directory(Task_identifier, &Relative_path) } - pub fn Delete(&self, Path: impl AsRef, Recursive: bool) -> Result<()> { + pub fn Delete(&self, Path: impl AsRef, Recursive: bool) -> Result_type<()> { if Recursive { todo!() } @@ -600,7 +570,7 @@ impl Virtual_file_system_type { &self, File: Unique_file_identifier_type, New_task: Task_identifier_type, - ) -> Result { + ) -> Result_type { let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems @@ -627,7 +597,7 @@ impl Virtual_file_system_type { )) } - pub fn Flush(&self, File: Unique_file_identifier_type) -> Result<()> { + pub fn Flush(&self, File: Unique_file_identifier_type) -> Result_type<()> { let (File_system_identifier, File_identifier) = File.Split(); if File_system_identifier == Self::Pipe_file_system_identifier { From be78b47e52ee785fb358d015bd16e38f5bb3c5ea Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:32:40 -0400 Subject: [PATCH 20/39] Make File_system_trait more general and refactor some function signature --- .../File_system/src/Generics/File_system.rs | 55 +++++++++++++------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/Modules/File_system/src/Generics/File_system.rs b/Modules/File_system/src/Generics/File_system.rs index 83ee73a..f2b9f47 100644 --- a/Modules/File_system/src/Generics/File_system.rs +++ b/Modules/File_system/src/Generics/File_system.rs @@ -1,8 +1,8 @@ use crate::Prelude::Mode_type; use super::{ - File_identifier_type, Flags_type, Path_owned_type, Path_type, Permissions_type, Position_type, - Result, Size_type, Type_type, + Device::Device_trait, Error_type, File_identifier_type, Flags_type, Path_owned_type, Path_type, + Permissions_type, Position_type, Result_type, Size_type, Status_type, Type_type, }; use Task::Task_identifier_type; @@ -10,6 +10,8 @@ use Users::{Group_identifier_type, User_identifier_type}; /// File system trait. /// +/// This allows to abstract the file system implementation. +/// The file system implementation should be registered in `Virtual_file_system_type`. /// The management of concurrent access to the file system is delegated to the implementation. /// Thus, implementation should use a `RwLock` or `Mutex` to manage concurrency. pub trait File_system_traits: Send + Sync { @@ -35,7 +37,7 @@ pub trait File_system_traits: Send + Sync { &self, Task: Task_identifier_type, Path: &dyn AsRef, - Mode: Flags_type, + Flags: Flags_type, ) -> Result_type; /// Close a file. @@ -90,7 +92,6 @@ pub trait File_system_traits: Send + Sync { fn Move( &self, - Task: Task_identifier_type, Source: &dyn AsRef, Destination: &dyn AsRef, ) -> Result_type<()>; @@ -105,7 +106,7 @@ pub trait File_system_traits: Send + Sync { File: File_identifier_type, Position: &Position_type, ) -> Result_type; - + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()>; // - Metadata @@ -136,7 +137,6 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the user / group doesn't have the permission to change the owner (not the current owner or not the root user). fn Set_owner( &self, - _: Task_identifier_type, _: &dyn AsRef, _: Option, _: Option, @@ -151,7 +151,6 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the user / group doesn't have the permission to get the owner (no execute permission on parent directory). fn Get_owner( &self, - _: Task_identifier_type, _: &dyn AsRef, ) -> Result_type<(User_identifier_type, Group_identifier_type)> { Ok((0, 0)) // TODO : Implement with permission file @@ -184,10 +183,23 @@ pub trait File_system_traits: Send + Sync { /// Returns an error if the directory / file already exists. /// Returns an error if the user / group doesn't have the permission to create the directory (no write permission on parent directory). fn Create_directory(&self, Path: &dyn AsRef) -> Result_type<()>; + + fn Create_named_pipe(&self, _: &dyn AsRef, _: Size_type) -> Result_type<()> { + Err(Error_type::Unsupported_operation) + } + + fn Add_device(&self, _: &dyn AsRef, _: Box) -> Result_type<()> { + Err(Error_type::Unsupported_operation) + } + + fn Create_unnamed_pipe( &self, - Task: Task_identifier_type, - Path: &dyn AsRef, - ) -> Result<()>; + _: Task_identifier_type, + _: Size_type, + _: Status_type, + ) -> Result_type<(File_identifier_type, File_identifier_type)> { + Err(Error_type::Unsupported_operation) + } /// Combine task identifier and file identifier to get a unique file identifier. fn Get_local_file_identifier( @@ -202,6 +214,17 @@ pub trait File_system_traits: Send + Sync { (Task_identifier) << 16 | File_identifier as u32 } + fn Decompose_local_file_identifier( + Local_file_identifier: u32, + ) -> (Task_identifier_type, File_identifier_type) + where + Self: Sized, // ? : Makes the compiler happy + { + let Task_identifier = Task_identifier_type::from(Local_file_identifier >> 16); + let File_identifier = File_identifier_type::from((Local_file_identifier & 0xFFFF) as u16); + (Task_identifier, File_identifier) + } + // - Tests /// Test the existence of a file. @@ -279,10 +302,9 @@ pub trait File_system_traits: Send + Sync { /// - Ensure `already_exists` exists in the `Test_path` directory fn Test_create_directory_exists(&self) { let New_path = Get_test_path().Append("test_dir").unwrap(); - let Task_identifier = Task_identifier_type::from(1); assert_eq!(self.Exists(&New_path), Ok(false)); - self.Create_directory(Task_identifier, &New_path).unwrap(); + self.Create_directory(&New_path).unwrap(); assert_eq!(self.Exists(&New_path), Ok(true)); } @@ -305,7 +327,7 @@ pub trait File_system_traits: Send + Sync { .unwrap(); assert_eq!(Size, 11); assert_eq!(&Buffer, b"0123456789\n"); - assert_eq!(self.Get_size(Task_identifier, &Read_file).unwrap(), 11); + assert_eq!(self.Get_size(&Read_file).unwrap(), 11); let Empty_file = Get_test_path().Append("empty_read").unwrap(); let Empty_file_identifier = self @@ -317,7 +339,7 @@ pub trait File_system_traits: Send + Sync { .Read(Task_identifier, Empty_file_identifier, &mut Buffer) .unwrap(); assert_eq!(Size, 0); - assert_eq!(self.Get_size(Task_identifier, &Empty_file).unwrap(), 0); + assert_eq!(self.Get_size(&Empty_file).unwrap(), 0); } /// Test write file operation. @@ -337,7 +359,7 @@ pub trait File_system_traits: Send + Sync { .Write(Task_identifier, File_identifier, Buffer) .unwrap(); assert_eq!(Size, 11); - assert_eq!(self.Get_size(Task_identifier, &File).unwrap(), 11); + assert_eq!(self.Get_size(&File).unwrap(), 11); } /// Run before the tests. @@ -345,8 +367,7 @@ pub trait File_system_traits: Send + Sync { let _ = self.Delete(&Get_test_path()); assert_eq!(self.Exists(&Get_test_path()), Ok(false)); - self.Create_directory(Task_identifier_type::from(1), &Get_test_path()) - .unwrap(); + self.Create_directory(&Get_test_path()).unwrap(); assert_eq!(self.Exists(&Get_test_path()), Ok(true)); } } From 6338a6aba30e311e9947e1c2e8d1d51ba837fdcd Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:33:19 -0400 Subject: [PATCH 21/39] Implement File_system_trait for Pipe Manager_type --- .../File_system/src/Generics/Pipe/Manager.rs | 471 +++++++++++------- 1 file changed, 278 insertions(+), 193 deletions(-) diff --git a/Modules/File_system/src/Generics/Pipe/Manager.rs b/Modules/File_system/src/Generics/Pipe/Manager.rs index 57a4534..b965bc6 100644 --- a/Modules/File_system/src/Generics/Pipe/Manager.rs +++ b/Modules/File_system/src/Generics/Pipe/Manager.rs @@ -1,205 +1,214 @@ -use std::{collections::HashMap, time::Duration}; +use std::{ + collections::{BTreeMap, HashMap}, + sync::RwLock, + time::Duration, +}; use Task::{Task_identifier_type, Task_type}; +use Users::{ + Group_identifier_type, Root_group_identifier, Root_user_identifier, User_identifier_type, +}; use crate::Prelude::{ - Error_type, File_identifier_type, Flags_type, Mode_type, Result, Size_type, Status_type, + Error_type, File_identifier_type, File_system_traits, Flags_type, Mode_type, Path_owned_type, + Path_type, Permissions_type, Result_type, Size_type, Status_type, Type_type, }; -#[derive(Eq, PartialEq, Hash, Clone, Copy)] -#[repr(transparent)] -pub struct Named_pipe_identifier_type(u32); - -impl Named_pipe_identifier_type { - pub const MAX: u32 = 0xFFFF_FFFF; -} - -impl From for Named_pipe_identifier_type { - fn from(Identifier: u32) -> Self { - Named_pipe_identifier_type(Identifier) - } -} - -impl From for u32 { - fn from(Identifier: Named_pipe_identifier_type) -> Self { - Identifier.0 - } -} +use super::Pipe_type; -impl From<[u8; 4]> for Named_pipe_identifier_type { - fn from(Identifier: [u8; 4]) -> Self { - Named_pipe_identifier_type(u32::from_ne_bytes(Identifier)) - } +struct Named_pipe_type { + Pipe: Pipe_type, + User: User_identifier_type, + Group: User_identifier_type, + Permissions: Permissions_type, } -impl From for [u8; 4] { - fn from(Identifier: Named_pipe_identifier_type) -> Self { - Identifier.0.to_ne_bytes() - } +struct Inner_type { + pub Named_pipes: HashMap, + pub Opened_pipes: BTreeMap, } -use super::Pipe_type; - -pub struct Manager_type { - Named_pipes: HashMap, - Opened_pipes: HashMap, -} +pub struct File_system_type(RwLock); -impl Manager_type { +impl File_system_type { pub fn New() -> Self { - Self { + Self(RwLock::new(Inner_type { Named_pipes: HashMap::new(), - Opened_pipes: HashMap::new(), - } - } - - fn Get_named_pipe_identifier(&self) -> Option { - (0..=Named_pipe_identifier_type::MAX) - .find(|&Identifier| !self.Named_pipes.contains_key(&Identifier.into())) - .map(|Identifier| Identifier.into()) - } - - fn Get_local_file_identifier( - Task_identifier: Task_identifier_type, - File_identifier: File_identifier_type, - ) -> u32 { - let File_identifier: u16 = File_identifier.into(); - let Task_identifier: u32 = Task_identifier.into(); - Task_identifier << 16 | File_identifier as u32 + Opened_pipes: BTreeMap::new(), + })) } + /// Get the local file identifier from the task identifier and the file identifier. + /// + /// Since the file identifier must remain valid, this method is static, and the lock + /// has to be acquired in the calling method. fn Get_new_file_identifier( - &self, - Task_identifier: Task_identifier_type, - ) -> Option { - let Start = Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0)); - let End = - Self::Get_local_file_identifier(Task_identifier, File_identifier_type::from(0xFFFF)); + Task: Task_identifier_type, + Opened_pipes: &BTreeMap, + ) -> Result_type { + let Start = Self::Get_local_file_identifier(Task, File_identifier_type::from(0)); + let End = Self::Get_local_file_identifier(Task, File_identifier_type::from(0xFFFF)); for File_identifier in Start..=End { - if !self.Opened_pipes.contains_key(&File_identifier) { - return Some(File_identifier_type::from(File_identifier as u16)); + if !Opened_pipes.contains_key(&File_identifier) { + return Ok(File_identifier_type::from(File_identifier as u16)); // Remove the task identifier and keep the file identifier. } } - None + Err(Error_type::Too_many_open_files) } +} - pub fn Create_named_pipe(&mut self, Size: usize) -> Result { - let Identifier = self - .Get_named_pipe_identifier() - .ok_or(Error_type::Too_many_open_files)?; - - self.Named_pipes.insert(Identifier, Pipe_type::New(Size)); +impl File_system_traits for File_system_type { + fn Create_named_pipe(&self, Path: &dyn AsRef, Size: Size_type) -> Result_type<()> { + let mut Inner = self.0.write()?; + + Inner.Named_pipes.insert( + Path.as_ref().to_owned(), + Named_pipe_type { + Pipe: Pipe_type::New(Size.into()), + User: Root_user_identifier, + Group: Root_group_identifier, + Permissions: Permissions_type::New_standard_file(), + }, + ); - Ok(Identifier) + Ok(()) } - pub fn Create_unnamed_pipe( - &mut self, + fn Create_unnamed_pipe( + &self, Task_identifier: Task_identifier_type, + Size: Size_type, Status: Status_type, - Size: usize, - ) -> Result<(File_identifier_type, File_identifier_type)> { - let Pipe = Pipe_type::New(Size); + ) -> Result_type<(File_identifier_type, File_identifier_type)> { + let Pipe = Pipe_type::New(Size.into()); + + let mut Inner = self.0.write()?; - let New_file_identifier_read = self - .Get_new_file_identifier(Task_identifier) - .ok_or(Error_type::Too_many_open_files)?; + let File_identifier_read = + Self::Get_new_file_identifier(Task_identifier, &Inner.Opened_pipes)?; - self.Opened_pipes.insert( - Self::Get_local_file_identifier(Task_identifier, New_file_identifier_read), + Inner.Opened_pipes.insert( + Self::Get_local_file_identifier(Task_identifier, File_identifier_read), ( Pipe.clone(), Flags_type::New(Mode_type::Read_only(), Some(Status)), ), ); - let New_file_identifier_write = self - .Get_new_file_identifier(Task_identifier) - .ok_or(Error_type::Too_many_open_files)?; + let File_identifier_write = + Self::Get_new_file_identifier(Task_identifier, &Inner.Opened_pipes)?; - self.Opened_pipes.insert( - Self::Get_local_file_identifier(Task_identifier, New_file_identifier_write), + Inner.Opened_pipes.insert( + Self::Get_local_file_identifier(Task_identifier, File_identifier_write), (Pipe, Flags_type::New(Mode_type::Write_only(), Some(Status))), ); - Ok((New_file_identifier_read, New_file_identifier_write)) + Ok((File_identifier_read, File_identifier_write)) } - pub fn Open( - &mut self, - Task_identifier: Task_identifier_type, - Identifier: Named_pipe_identifier_type, + fn Exists(&self, Path: &dyn AsRef) -> Result_type { + Ok(self.0.read()?.Named_pipes.contains_key(Path.as_ref())) + } + + fn Create_file(&self, _: &dyn AsRef) -> Result_type<()> { + Result_type::Err(Error_type::Unsupported_operation) + } + + fn Open( + &self, + Task: Task_identifier_type, + Path: &dyn AsRef, Flags: Flags_type, - ) -> Result { - let Named_pipe = self + ) -> Result_type { + let mut Inner = self.0.write()?; + + let Named_pipe = Inner .Named_pipes - .get(&Identifier) - .ok_or(Error_type::Not_found)?; + .get(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Pipe + .clone(); - let File_identifier = self - .Get_new_file_identifier(Task_identifier) - .ok_or(Error_type::Too_many_open_files)?; + let File_identifier = Self::Get_new_file_identifier(Task, &Inner.Opened_pipes)?; - let Local_file_identifier = - Self::Get_local_file_identifier(Task_identifier, File_identifier); + let Local_file_identifier = Self::Get_local_file_identifier(Task, File_identifier); - self.Opened_pipes - .insert(Local_file_identifier, (Named_pipe.clone(), Flags)); + Inner + .Opened_pipes + .insert(Local_file_identifier, (Named_pipe, Flags)); Ok(File_identifier) } - pub fn Close( - &mut self, - Task: Task::Task_identifier_type, - File: File_identifier_type, - ) -> Result<()> { - let Local_file_identifier = Self::Get_local_file_identifier(Task, File); - - self.Opened_pipes - .remove(&Local_file_identifier) + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()> { + self.0 + .write()? + .Opened_pipes + .remove(&Self::Get_local_file_identifier(Task, File)) .ok_or(Error_type::Invalid_identifier)?; Ok(()) } - pub fn Close_all(&mut self, Task: Task::Task_identifier_type) -> Result<()> { - let Start = Self::Get_local_file_identifier(Task, File_identifier_type::from(0)); - let End = Self::Get_local_file_identifier(Task, File_identifier_type::from(0xFFFF)); - - self.Opened_pipes.retain(|Key, _| { - if *Key >= Start && *Key <= End { - return false; - } - true - }); + fn Close_all(&self, Task: Task_identifier_type) -> Result_type<()> { + self.0 + .write()? + .Opened_pipes + .retain(|Key, _| Self::Decompose_local_file_identifier(*Key).0 != Task); Ok(()) } - pub fn Delete(&mut self, Identifier: Named_pipe_identifier_type) -> Result<()> { - self.Named_pipes - .remove(&Identifier) - .ok_or(Error_type::Not_found)?; + fn Transfert_file_identifier( + &self, + Old_task: Task_identifier_type, + New_task: Task_identifier_type, + File: File_identifier_type, + ) -> Result_type { + let Local_file_identifier = Self::Get_local_file_identifier(Old_task, File); + + let mut Inner = self.0.write()?; - // The pipe is still opened by some tasks until they close it. - // The pipe will be deleted when the last task closes it. + let New_file_identifier = Self::Get_new_file_identifier(New_task, &Inner.Opened_pipes)?; + + let (Pipe, Mode) = Inner + .Opened_pipes + .remove(&Local_file_identifier) + .ok_or(Error_type::Invalid_identifier)?; + + let Local_file_identifier = Self::Get_local_file_identifier(New_task, New_file_identifier); + + Inner + .Opened_pipes + .insert(Local_file_identifier, (Pipe, Mode)); + + Ok(New_file_identifier) + } + + fn Delete(&self, Path: &dyn AsRef) -> Result_type<()> { + self.0 + .write()? + .Named_pipes + .remove(Path.as_ref()) + .ok_or(Error_type::Not_found)?; Ok(()) } - pub fn Read( - &mut self, - Task: Task::Task_identifier_type, + fn Read( + &self, + Task: Task_identifier_type, File: File_identifier_type, Buffer: &mut [u8], - ) -> Result { + ) -> Result_type { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); - let (Pipe, Flags) = self + let Inner = self.0.read()?; + + let (Pipe, Flags) = Inner .Opened_pipes .get(&Local_file_identifier) .ok_or(Error_type::Invalid_identifier)?; @@ -209,7 +218,7 @@ impl Manager_type { } while let Err(Error) = Pipe.Read(Buffer) { - if let Error_type::File_system_full = Error { + if let Error_type::Ressource_busy = Error { if Flags.Get_status().Get_non_blocking() { return Err(Error_type::Ressource_busy); } else { @@ -223,15 +232,17 @@ impl Manager_type { Ok(Buffer.len().into()) } - pub fn Write( - &mut self, - Task: Task::Task_identifier_type, + fn Write( + &self, + Task: Task_identifier_type, File: File_identifier_type, Buffer: &[u8], - ) -> Result { + ) -> Result_type { let Local_file_identifier = Self::Get_local_file_identifier(Task, File); - let (Pipe, Mode) = self + let Inner = self.0.read()?; + + let (Pipe, Mode) = Inner .Opened_pipes .get(&Local_file_identifier) .ok_or(Error_type::Invalid_identifier)?; @@ -241,7 +252,7 @@ impl Manager_type { } while let Err(Error) = Pipe.Write(Buffer) { - if let Error_type::File_system_full = Error { + if let Error_type::Ressource_busy = Error { if Mode.Get_status().Get_non_blocking() { return Err(Error_type::Ressource_busy); } else { @@ -255,36 +266,115 @@ impl Manager_type { Ok(Buffer.len().into()) } - pub fn Get_size(&self, Identifier: Named_pipe_identifier_type) -> Result { - self.Named_pipes - .get(&Identifier) + fn Move( + &self, + Source: &dyn AsRef, + Destination: &dyn AsRef, + ) -> Result_type<()> { + let mut Inner = self.0.write()?; + + let Pipe = Inner + .Named_pipes + .remove(Source.as_ref()) + .ok_or(Error_type::Not_found)?; + + Inner + .Named_pipes + .insert(Destination.as_ref().to_owned(), Pipe); + + Ok(()) + } + + fn Set_position( + &self, + _: Task_identifier_type, + _: File_identifier_type, + _: &crate::Prelude::Position_type, + ) -> Result_type { + Err(Error_type::Unsupported_operation) + } + + fn Flush(&self, _: Task_identifier_type, _: File_identifier_type) -> Result_type<()> { + Ok(()) + } + + fn Get_type(&self, _: &dyn AsRef) -> Result_type { + Ok(Type_type::Named_pipe) + } + + fn Get_size(&self, Path: &dyn AsRef) -> Result_type { + self.0 + .read()? + .Named_pipes + .get(Path.as_ref()) .ok_or(Error_type::Not_found)? + .Pipe .Get_size() } - pub fn Transfert_file_identifier( - &mut self, - Old_task: Task_identifier_type, - New_task: Task_identifier_type, - File: File_identifier_type, - ) -> Result { - let Local_file_identifier = Self::Get_local_file_identifier(Old_task, File); + fn Create_directory(&self, _: &dyn AsRef) -> Result_type<()> { + Err(Error_type::Unsupported_operation) + } - let (Pipe, Mode) = self - .Opened_pipes - .remove(&Local_file_identifier) - .ok_or(Error_type::Invalid_identifier)?; + fn Set_permissions( + &self, + Path: &dyn AsRef, + Permissions_type: Permissions_type, + ) -> Result_type<()> { + self.0 + .write()? + .Named_pipes + .get_mut(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Permissions = Permissions_type; - let New_file_identifier = self - .Get_new_file_identifier(New_task) - .ok_or(Error_type::Too_many_open_files)?; + Ok(()) + } - let Local_file_identifier = Self::Get_local_file_identifier(New_task, New_file_identifier); + fn Get_permissions(&self, Path: &dyn AsRef) -> Result_type { + Ok(self + .0 + .read()? + .Named_pipes + .get(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Permissions) + } - self.Opened_pipes - .insert(Local_file_identifier, (Pipe, Mode)); + fn Get_owner( + &self, + Path: &dyn AsRef, + ) -> Result_type<(User_identifier_type, Group_identifier_type)> { + self.0 + .read()? + .Named_pipes + .get(Path.as_ref()) + .ok_or(Error_type::Not_found) + .map(|Named_pipe| (Named_pipe.User, Named_pipe.Group)) + } - Ok(New_file_identifier) + fn Set_owner( + &self, + Path: &dyn AsRef, + User: Option, + Group: Option, + ) -> Result_type<()> { + let mut Inner = self.0.write()?; + + let Named_pipe = Inner + .Named_pipes + .get_mut(Path.as_ref()) + .ok_or(Error_type::Not_found)?; + + if let Some(User) = User { + Named_pipe.User = User; + } + + if let Some(Group) = Group { + Named_pipe.Group = Group; + } + + Ok(()) } } @@ -294,9 +384,9 @@ mod tests { #[test] fn Test_new() { - let File_system = Manager_type::New(); - assert!(File_system.Named_pipes.is_empty()); - assert!(File_system.Opened_pipes.is_empty()); + let File_system = File_system_type::New(); + assert!(File_system.0.read().unwrap().Named_pipes.is_empty()); + assert!(File_system.0.read().unwrap().Opened_pipes.is_empty()); } #[test] @@ -304,89 +394,84 @@ mod tests { let Task_identifier = Task_identifier_type::from(1); let File_identifier = File_identifier_type::from(0); let local_file_id = - Manager_type::Get_local_file_identifier(Task_identifier, File_identifier); + File_system_type::Get_local_file_identifier(Task_identifier, File_identifier); assert_eq!(local_file_id, 65536); // 1 << 16 | 0 } #[test] fn Test_new_unnamed_pipe() { - let mut File_system = Manager_type::New(); + let File_system = File_system_type::New(); let Task_identifier = Task_identifier_type::from(1); - let Size = 1024; + let Size = 1024_usize; let (Read_identifier, Write_identifier) = File_system .Create_unnamed_pipe( Task_identifier, + Size.into(), Status_type::default().Set_non_blocking(true), - Size, ) .unwrap(); assert_ne!(Read_identifier, Write_identifier); - assert!(File_system - .Opened_pipes - .contains_key(&Manager_type::Get_local_file_identifier( - Task_identifier, - Read_identifier - ))); - assert!(File_system - .Opened_pipes - .contains_key(&Manager_type::Get_local_file_identifier( - Task_identifier, - Write_identifier - ))); + assert!(File_system.0.read().unwrap().Opened_pipes.contains_key( + &File_system_type::Get_local_file_identifier(Task_identifier, Read_identifier) + )); + assert!(File_system.0.read().unwrap().Opened_pipes.contains_key( + &File_system_type::Get_local_file_identifier(Task_identifier, Write_identifier) + )); } #[test] fn Test_close_all() { - let mut File_system = Manager_type::New(); + let File_system = File_system_type::New(); let Task_identifier = Task_identifier_type::from(1); - let Size = 1024; + let Size = 1024_usize; File_system .Create_unnamed_pipe( Task_identifier, + Size.into(), Status_type::default().Set_non_blocking(true), - Size, ) .unwrap(); File_system .Create_unnamed_pipe( Task_identifier, + Size.into(), Status_type::default().Set_non_blocking(true), - Size, ) .unwrap(); File_system .Create_unnamed_pipe( Task_identifier, + Size.into(), Status_type::default().Set_non_blocking(true), - Size, ) .unwrap(); File_system.Close_all(Task_identifier).unwrap(); - assert!(File_system.Opened_pipes.is_empty()); + assert!(File_system.0.read().unwrap().Opened_pipes.is_empty()); } #[test] fn Test_delete_named_pipe() { - let mut File_system = Manager_type::New(); + let File_system = File_system_type::New(); - let Size = 1024; + let Size = 1024_usize; + let Path = Path_type::New("/named_pipe").unwrap(); - let Identifier = File_system.Create_named_pipe(Size).unwrap(); - assert!(File_system.Delete(Identifier).is_ok()); - assert!(File_system.Named_pipes.is_empty()); - assert!(File_system.Delete(Identifier).is_err()); + File_system.Create_named_pipe(&Path, Size.into()).unwrap(); + assert!(File_system.Delete(&Path).is_ok()); + assert!(File_system.0.read().unwrap().Named_pipes.is_empty()); + assert!(File_system.Delete(&Path).is_err()); } #[test] fn Test_read_write_unnamed_pipe() { - let mut File_system = Manager_type::New(); + let File_system = File_system_type::New(); let Task_identifier = Task_identifier_type::from(1); - let Size = 1024; + let Size = 1024_usize; let (Read_identifier, Write_identifier) = File_system .Create_unnamed_pipe( Task_identifier, + Size.into(), Status_type::default().Set_non_blocking(true), - Size, ) .unwrap(); From 73ba5dd7583bb1ee8fbac05d9db39e7a6ea3b963 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:33:54 -0400 Subject: [PATCH 22/39] Fix bugs in native file system drivers --- Modules/File_system/src/Drivers/Native/mod.rs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Modules/File_system/src/Drivers/Native/mod.rs b/Modules/File_system/src/Drivers/Native/mod.rs index d982d2e..7c6ccca 100644 --- a/Modules/File_system/src/Drivers/Native/mod.rs +++ b/Modules/File_system/src/Drivers/Native/mod.rs @@ -126,7 +126,11 @@ impl File_system_type { pub fn Get_full_path(&self, Path: &dyn AsRef) -> Result_type { self.Virtual_root_path .clone() - .Join(Path) + .Join( + Path.as_ref() + .Strip_prefix(Path_type::Get_root()) + .ok_or(Error_type::Invalid_path)?, + ) .ok_or(Error_type::Invalid_path) } } @@ -157,14 +161,14 @@ impl File_system_traits for File_system_type { .open(Full_path.as_ref() as &Path_type) .map_err(|Error| Error.kind())?; - let File_identifier = self.Get_new_file_identifier(Task_identifier)?; + let mut Open_files = self.Open_files.write()?; + + let File_identifier = Self::Get_new_file_identifier(Task_identifier, &Open_files)?; let Local_file_identifier = Self::Get_local_file_identifier(Task_identifier, File_identifier); - if self - .Open_files - .write()? + if Open_files .insert(Local_file_identifier, RwLock::new(File)) .is_some() { @@ -307,12 +311,13 @@ impl File_system_traits for File_system_type { ) -> Result_type { let Old_local_file_identifier = Self::Get_local_file_identifier(Old_task, Old_file_identifier); - let New_file_identifier = self.Get_new_file_identifier(New_task)?; - let New_local_file_identifier = - Self::Get_local_file_identifier(New_task, New_file_identifier); let mut Open_files = self.Open_files.write()?; + let New_file_identifier = Self::Get_new_file_identifier(New_task, &Open_files)?; + let New_local_file_identifier = + Self::Get_local_file_identifier(New_task, New_file_identifier); + let File = Open_files .remove(&Old_local_file_identifier) .ok_or(Error_type::Invalid_identifier)?; From d5cd3bc86206080d15502027f22dec2d241e9b23 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:34:31 -0400 Subject: [PATCH 23/39] Implement Debug for File_type --- Modules/File_system/src/Generics/File.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Modules/File_system/src/Generics/File.rs b/Modules/File_system/src/Generics/File.rs index c123717..817881d 100644 --- a/Modules/File_system/src/Generics/File.rs +++ b/Modules/File_system/src/Generics/File.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use super::{ Flags_type, Path_type, Position_type, Result_type, Size_type, Status_type, Unique_file_identifier_type, Virtual_file_system::Virtual_file_system_type, @@ -16,7 +18,17 @@ pub enum Type_type { pub struct File_type { File_identifier: Unique_file_identifier_type, - File_system: Virtual_file_system_type, + File_system: &'static Virtual_file_system_type, +} + +impl Debug for File_type { + fn fmt(&self, Formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Formatter + .debug_struct("File_type") + .field("File_identifier", &self.File_identifier) + .field("File_system", &(self.File_system as *const _)) + .finish() + } } impl File_type { From dd13ea48b61b97d0121c8c249bee5c3fe425f6c5 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:35:20 -0400 Subject: [PATCH 24/39] Write device trait --- Modules/File_system/src/Generics/Device/Device.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Modules/File_system/src/Generics/Device/Device.rs diff --git a/Modules/File_system/src/Generics/Device/Device.rs b/Modules/File_system/src/Generics/Device/Device.rs new file mode 100644 index 0000000..6c0b271 --- /dev/null +++ b/Modules/File_system/src/Generics/Device/Device.rs @@ -0,0 +1,13 @@ +use crate::Prelude::{Position_type, Result_type}; + +pub trait Device_trait: Send + Sync { + fn Read(&self, Buffer: &mut [u8]) -> Result_type; + + fn Write(&self, Buffer: &[u8]) -> Result_type; + + fn Get_size(&self) -> Result_type; + + fn Set_position(&self, Position: &Position_type) -> Result_type; + + fn Flush(&self) -> Result_type<()>; +} From 631f26a95a2094a73c4d1238a3757cccfe31e2fa Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:35:43 -0400 Subject: [PATCH 25/39] Implement file system for device --- .../src/Generics/Device/File_system.rs | 328 ++++++++++++++++++ .../File_system/src/Generics/Device/mod.rs | 6 + 2 files changed, 334 insertions(+) create mode 100644 Modules/File_system/src/Generics/Device/File_system.rs create mode 100644 Modules/File_system/src/Generics/Device/mod.rs diff --git a/Modules/File_system/src/Generics/Device/File_system.rs b/Modules/File_system/src/Generics/Device/File_system.rs new file mode 100644 index 0000000..74b281f --- /dev/null +++ b/Modules/File_system/src/Generics/Device/File_system.rs @@ -0,0 +1,328 @@ +use std::{ + collections::{BTreeMap, HashMap}, + sync::{Arc, RwLock}, +}; + +use Task::Task_identifier_type; +use Users::{ + Group_identifier_type, Root_group_identifier, Root_user_identifier, User_identifier_type, +}; + +use crate::Prelude::{ + Error_type, File_identifier_type, File_system_traits, Flags_type, Path_owned_type, Path_type, + Permissions_type, Position_type, Result_type, Size_type, Type_type, +}; + +use super::Device_trait; + +struct Internal_device_type { + pub Device: Arc>, + pub User: User_identifier_type, + pub Group: User_identifier_type, + pub Permissions: Permissions_type, +} + +struct Inner_type { + Devices: HashMap, + Opened_devices: BTreeMap>, Flags_type)>, +} + +pub struct File_system_type(RwLock); + +impl File_system_type { + pub fn New() -> Self { + Self(RwLock::new(Inner_type { + Devices: HashMap::new(), + Opened_devices: BTreeMap::new(), + })) + } + + fn Get_new_file_identifier( + &self, + Task: Task_identifier_type, + ) -> Result_type { + let Start = Self::Get_local_file_identifier(Task, File_identifier_type::from(0)); + let End = Self::Get_local_file_identifier(Task, File_identifier_type::from(0xFFFF)); + + for File_identifier in Start..=End { + if !self.0.read()?.Opened_devices.contains_key(&File_identifier) { + return Ok(File_identifier_type::from(File_identifier as u16)); + // Remove the task identifier and keep the file identifier. + } + } + + Err(Error_type::Too_many_open_files) + } +} + +impl File_system_traits for File_system_type { + fn Exists(&self, Path: &dyn AsRef) -> Result_type { + Ok(self.0.read()?.Devices.contains_key(Path.as_ref())) + } + + fn Create_file(&self, _: &dyn AsRef) -> Result_type<()> { + Err(Error_type::Unsupported_operation) + } + + fn Open( + &self, + Task: Task_identifier_type, + Path: &dyn AsRef, + Flags: crate::Prelude::Flags_type, + ) -> Result_type { + let Opened_device = self + .0 + .read() + .unwrap() + .Devices + .get(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Device + .clone(); + + let File_identifier = self.Get_new_file_identifier(Task)?; + + self.0.write()?.Opened_devices.insert( + Self::Get_local_file_identifier(Task, File_identifier), + (Opened_device, Flags), + ); + + Ok(File_identifier) + } + + fn Close(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()> { + self.0 + .write()? + .Opened_devices + .remove(&Self::Get_local_file_identifier(Task, File)) + .ok_or(Error_type::Not_found)?; + + Ok(()) + } + + fn Close_all(&self, Task: Task_identifier_type) -> Result_type<()> { + self.0 + .write()? + .Opened_devices + .retain(|Key, _| Self::Decompose_local_file_identifier(*Key).0 != Task); + + Ok(()) + } + + fn Transfert_file_identifier( + &self, + Old_task: Task_identifier_type, + New_task: Task_identifier_type, + File: File_identifier_type, + ) -> Result_type { + let File_identifier = Self::Get_local_file_identifier(Old_task, File); + + let (Device, Flags) = self + .0 + .write()? + .Opened_devices + .remove(&File_identifier) + .ok_or(Error_type::Not_found)?; + + let New_file_identifier = self.Get_new_file_identifier(New_task)?; + + self.0.write()?.Opened_devices.insert( + Self::Get_local_file_identifier(New_task, New_file_identifier), + (Device, Flags), + ); + + Ok(New_file_identifier) + } + + fn Delete(&self, Path: &dyn AsRef) -> Result_type<()> { + self.0 + .write()? + .Devices + .remove(Path.as_ref()) + .ok_or(Error_type::Not_found)?; + + Ok(()) + } + + fn Read( + &self, + Task: Task_identifier_type, + File: File_identifier_type, + Buffer: &mut [u8], + ) -> Result_type { + self.0 + .read()? + .Opened_devices + .get(&Self::Get_local_file_identifier(Task, File)) + .ok_or(Error_type::Not_found)? + .0 + .Read(Buffer) + .map(|Size| Size.into()) + } + + fn Write( + &self, + Task: Task_identifier_type, + File: File_identifier_type, + Buffer: &[u8], + ) -> Result_type { + self.0 + .read()? + .Opened_devices + .get(&Self::Get_local_file_identifier(Task, File)) + .ok_or(Error_type::Not_found)? + .0 + .Write(Buffer) + .map(|Size| Size.into()) + } + + fn Move( + &self, + Source: &dyn AsRef, + Destination: &dyn AsRef, + ) -> Result_type<()> { + let Removed = self + .0 + .write()? + .Devices + .remove(Source.as_ref()) + .ok_or(Error_type::Not_found)?; + + self.0 + .write()? + .Devices + .insert(Destination.as_ref().to_owned(), Removed); + + Ok(()) + } + + fn Set_position( + &self, + Task: Task_identifier_type, + File: File_identifier_type, + Position: &Position_type, + ) -> Result_type { + self.0 + .read()? + .Opened_devices + .get(&Self::Get_local_file_identifier(Task, File)) + .ok_or(Error_type::Not_found)? + .0 + .Set_position(Position) + .map(|Size| Size.into()) + } + + fn Flush(&self, Task: Task_identifier_type, File: File_identifier_type) -> Result_type<()> { + self.0 + .read()? + .Opened_devices + .get(&Self::Get_local_file_identifier(Task, File)) + .ok_or(Error_type::Not_found)? + .0 + .Flush() + } + + fn Get_type(&self, _: &dyn AsRef) -> Result_type { + Ok(Type_type::Character_device) + } + + fn Get_size(&self, Path: &dyn AsRef) -> Result_type { + self.0 + .read()? + .Devices + .get(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Device + .Get_size() + .map(|Size| Size.into()) + } + + fn Create_directory(&self, _: &dyn AsRef) -> Result_type<()> { + Err(Error_type::Unsupported_operation) + } + + fn Add_device( + &self, + Path: &dyn AsRef, + Device: Box, + ) -> Result_type<()> { + let Inner = &mut self.0.write()?; + + if Inner.Devices.contains_key(Path.as_ref()) { + return Err(Error_type::Already_exists); + } + + Inner.Devices.insert( + Path.as_ref().to_owned(), + Internal_device_type { + Device: Arc::new(Device), + User: Root_user_identifier, + Group: Root_group_identifier, + Permissions: Permissions_type::New_standard_file(), + }, + ); + + Ok(()) + } + + fn Set_permissions( + &self, + Path: &dyn AsRef, + Permissions: Permissions_type, + ) -> Result_type<()> { + self.0 + .write()? + .Devices + .get_mut(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Permissions = Permissions; + + Ok(()) + } + + fn Get_permissions(&self, Path: &dyn AsRef) -> Result_type { + Ok(self + .0 + .read()? + .Devices + .get(Path.as_ref()) + .ok_or(Error_type::Not_found)? + .Permissions) + } + + fn Set_owner( + &self, + Path: &dyn AsRef, + User: Option, + Group: Option, + ) -> Result_type<()> { + let mut Inner = self.0.write()?; + + let Device = Inner + .Devices + .get_mut(Path.as_ref()) + .ok_or(Error_type::Not_found)?; + + if let Some(User) = User { + Device.User = User; + } + + if let Some(Group) = Group { + Device.Group = Group; + } + + Ok(()) + } + + fn Get_owner( + &self, + Path: &dyn AsRef, + ) -> Result_type<(User_identifier_type, Group_identifier_type)> { + self.0 + .read()? + .Devices + .get(Path.as_ref()) + .map(|Device| (Device.User, Device.Group)) + .ok_or(Error_type::Not_found) + } +} diff --git a/Modules/File_system/src/Generics/Device/mod.rs b/Modules/File_system/src/Generics/Device/mod.rs new file mode 100644 index 0000000..b9304dc --- /dev/null +++ b/Modules/File_system/src/Generics/Device/mod.rs @@ -0,0 +1,6 @@ +#[allow(clippy::module_inception)] +mod Device; +mod File_system; + +pub use Device::*; +pub use File_system::*; From d35ee42b602a4d04af5278b891d31398c89a4caf Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:36:05 -0400 Subject: [PATCH 26/39] Add Device module and export Device_trait --- Modules/File_system/src/Generics/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/File_system/src/Generics/mod.rs b/Modules/File_system/src/Generics/mod.rs index fe4b76d..d3eb7e3 100644 --- a/Modules/File_system/src/Generics/mod.rs +++ b/Modules/File_system/src/Generics/mod.rs @@ -1,3 +1,4 @@ +mod Device; mod Error; mod File; mod File_system; @@ -5,6 +6,7 @@ mod Fundamentals; mod Pipe; mod Virtual_file_system; +pub use Device::Device_trait; pub use Error::*; pub use File::*; pub use File_system::*; From 437ee375399b9819284fc0e3164bc976922fec1d Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:38:11 -0400 Subject: [PATCH 27/39] Refactor Virtual file system to handle device and file as regular file system --- .../src/Generics/Virtual_file_system.rs | 669 +++++++++--------- 1 file changed, 320 insertions(+), 349 deletions(-) diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index 5170bf9..e754432 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -1,17 +1,16 @@ use std::{collections::BTreeMap, sync::RwLock}; use Task::Task_identifier_type; -use Users::{Group_identifier_type, Manager_type, User_identifier_type}; +use Users::{Group_identifier_type, User_identifier_type}; use super::{ - Error_type, File_system_identifier_type, File_system_traits, Flags_type, Mode_type, - Path_owned_type, Path_type, Permissions_type, - Pipe::{self, Named_pipe_identifier_type}, - Position_type, Result, Size_type, Status_type, Type_type, Unique_file_identifier_type, + Device, Device_trait, Error_type, File_system_identifier_type, File_system_traits, Flags_type, + Path_owned_type, Path_type, Permission_type, Permissions_type, Pipe, Position_type, + Result_type, Size_type, Status_type, Type_type, Unique_file_identifier_type, }; struct Internal_file_system_type { - pub Mount_point: Path_owned_type, + pub Mount_point: Option, pub Inner: Box, } @@ -27,54 +26,144 @@ pub struct Virtual_file_system_type { impl Virtual_file_system_type { const Pipe_file_system_identifier: File_system_identifier_type = - File_system_identifier_type::New_from(0xFF); + File_system_identifier_type::New(0); + const Device_file_system_identifier: File_system_identifier_type = + File_system_identifier_type::New(1); - const Named_pipe_extension: &'static str = ".Xila_pipe"; + fn New( + Task_manager: Task::Manager_type, + User_manager: Users::Manager_type, + ) -> Result_type { + let mut File_systems = BTreeMap::new(); - pub fn New(Task_manager: Task::Manager_type, User_manager: Users::Manager_type) -> Self { - Virtual_file_system_type { + let Pipe_file_system = Pipe::File_system_type::New(); + + File_systems.insert( + Self::Pipe_file_system_identifier, + Internal_file_system_type { + Mount_point: None, + Inner: Box::new(Pipe_file_system), + }, + ); + + let Device_file_system = Device::File_system_type::New(); + + File_systems.insert( + Self::Device_file_system_identifier, + Internal_file_system_type { + Mount_point: None, + Inner: Box::new(Device_file_system), + }, + ); + + Ok(Self { Task_manager, User_manager, - File_systems: Arc::new(RwLock::new(HashMap::new())), - Pipes_file_system: Arc::new(RwLock::new(Pipe::Manager_type::New())), - } + File_systems: RwLock::new(File_systems), + }) } - fn Get_new_file_system_identifier(&self) -> Option { - let File_systems = self.File_systems.read().ok()?; + fn Get_new_file_system_identifier( + File_systems: &BTreeMap, + ) -> Option { + let mut File_system_identifier = File_system_identifier_type::New(0); - let mut File_system_identifier = File_system_identifier_type::New(); - - while File_systems.contains_key(&File_system_identifier) - || File_system_identifier == Self::Pipe_file_system_identifier - { + while File_systems.contains_key(&File_system_identifier) { File_system_identifier += 1; } Some(File_system_identifier) } + /// Try to execute a closure on the concerned file systems on an **existing** file. + fn Try_on_concerned_file_systems( + &self, + Path: impl AsRef, + Closure: F, + ) -> Result_type + where + F: Fn( + File_system_identifier_type, + &Internal_file_system_type, + &Path_type, + ) -> Result_type, + { + let mut Result_score = 0; + let mut Result: Option<(File_system_identifier_type, &Internal_file_system_type)> = None; + + let File_systems = self.File_systems.read()?; + + // Try with mounted file systems. + for (File_system_identifier, File_system) in File_systems.iter() { + if let Some(Mount_point) = &File_system.Mount_point { + let Mount_point: &Path_type = Mount_point.as_ref(); + if let Some(Relative_path) = Path.as_ref().Strip_prefix_absolute(Mount_point) { + let Score = Relative_path.Get_length(); + if Score > Result_score { + Result_score = Score; + Result = Some((*File_system_identifier, File_system)); + } + } + } + } + + // If a file system is found and the file exists, return the result of the closure. + if let Some((File_system_identifier, File_system)) = Result { + match Closure(File_system_identifier, File_system, Path.as_ref()) { + Ok(Result) => return Ok(Result), + Err(Error_type::Not_found) => (), // Continue when the file is not found. + Err(Error) => return Err(Error), + } + } + + // Try with special file systems. + for (File_system_identifier, File_system) in File_systems.iter() { + if File_system.Mount_point.is_none() { + match Closure(*File_system_identifier, File_system, Path.as_ref()) { + Ok(Result) => return Ok(Result), + Err(Error_type::Not_found) => (), // Continue when the file is not found. + Err(Error) => return Err(Error), + } + } + } + + Err(Error_type::Not_found) + } + + fn Get_file_system_from_identifier( + File_systems: &BTreeMap, + File_system_identifier: File_system_identifier_type, + ) -> Result_type<&Internal_file_system_type> { + File_systems + .get(&File_system_identifier) + .ok_or(Error_type::Invalid_identifier) + } + /// Mount a file system at a given mount point. pub fn Mount( &self, File_system: Box, Mount_point: impl AsRef, ) -> Result_type { + let Mount_point = Mount_point.as_ref(); + + if !Mount_point.Is_absolute() { + return Err(Error_type::Invalid_path); + } + + if self.Exists(Mount_point)? { return Err(Error_type::Already_exists); } - let File_system_identifier = self - .Get_new_file_system_identifier() - .ok_or(Error_type::Too_many_mounted_file_systems)?; + let mut File_systems = self.File_systems.write()?; - if !Mount_point.as_ref().Is_absolute() { - return Err(Error_type::Invalid_path); - } + let File_system_identifier = Self::Get_new_file_system_identifier(&File_systems) + .ok_or(Error_type::Too_many_mounted_file_systems)?; - self.File_systems.write()?.insert( + File_systems.insert( File_system_identifier, Internal_file_system_type { - Mount_point: Mount_point.as_ref().to_owned(), + Mount_point: Some(Mount_point.to_owned()), Inner: File_system, }, ); @@ -82,27 +171,47 @@ impl Virtual_file_system_type { Ok(File_system_identifier) } + /// Unmount a file system and return the file system. + pub fn Unmount( + &self, + File_system_identifier: File_system_identifier_type, ) -> Result_type> { + let Internal_file_system = self + .File_systems .write()? .remove(&File_system_identifier) .ok_or(Error_type::Invalid_identifier)?; - Ok(()) + Ok(Internal_file_system.Inner) } - fn Get_file_system<'b>( - File_systems: &'b HashMap, + fn Get_file_system_from_mount_point<'b>( + File_systems: &'b BTreeMap, Path: &'b dyn AsRef, - ) -> Result<(File_system_identifier_type, &'b Path_type)> { + ) -> Result_type<( + File_system_identifier_type, + &'b dyn File_system_traits, + &'b Path_type, + )> { let mut Result_score = 0; - let mut Result: Option<(File_system_identifier_type, &'b Path_type)> = None; + let mut Result: Option<( + File_system_identifier_type, + &'b dyn File_system_traits, + &'b Path_type, + )> = None; for (File_system_identifier, File_system) in File_systems.iter() { - if let Some(Relative_path) = Path.as_ref().Strip_prefix(&File_system.Mount_point) { - let Score = Relative_path.Get_length(); - if Score > Result_score { - Result_score = Score; - Result = Some((*File_system_identifier, Relative_path)); + if let Some(Mount_point) = &File_system.Mount_point { + if let Some(Relative_path) = Path.as_ref().Strip_prefix_absolute(Mount_point) { + let Score = Relative_path.Get_length(); + if Score > Result_score { + Result_score = Score; + Result = Some(( + *File_system_identifier, + File_system.Inner.as_ref(), + Relative_path, + )); + } } } } @@ -114,71 +223,56 @@ impl Virtual_file_system_type { &self, Path: impl AsRef, Flags: Flags_type, - ) -> Result { - let File_systems = self.File_systems.read()?; // Get the file systems - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - + ) -> Result_type { let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - // - Check permissions - - self.Check_permissions(File_system, Task_identifier, Relative_path, Flags)?; - // - Open file - - match File_system - .Inner - .Open(Task_identifier, &Relative_path, Flags) - { - Ok(File_identifier) => Ok(Unique_file_identifier_type::New( - File_system_identifier, - File_identifier, - )), - Err(Error_type::Invalid_path) => { - if let Some(Self::Named_pipe_extension) = Relative_path.Get_extension() { - return Err(Error_type::Invalid_path); - } - - self.Open_named_pipe(Relative_path, Flags) - } - - Err(e) => Err(e), - } + self.Try_on_concerned_file_systems( + Path, + |File_system_identifier, File_system, Relative_path| { + File_system + .Inner + .Open(Task_identifier, &Relative_path, Flags) + .map(|File_identifier| { + Unique_file_identifier_type::New(File_system_identifier, File_identifier) + }) + }, + ) } - fn Check_permissions( + fn Get_permission( &self, - File_system: &Internal_file_system_type, + File_system: &dyn File_system_traits, Task_identifier: Task_identifier_type, Relative_path: impl AsRef, - Flags: Flags_type, - ) -> Result<()> { - // - Check permissions - - let Permissions = File_system - .Inner - .Get_permissions(Task_identifier, &Relative_path)?; - - let (Owner_user, Owner_group) = File_system - .Inner - .Get_owner(Task_identifier, &Relative_path)?; + ) -> Result_type { + let (File_user, File_group) = File_system.Get_owner(&Relative_path)?; let Task_user = self.Task_manager.Get_owner(Task_identifier)?; - let Permission = if Task_user == Owner_user { - Permissions.Get_user() - } else if self.User_manager.Is_in_group(Task_user, Owner_group) { - Permissions.Get_group() + let File_permissions = File_system.Get_permissions(&Relative_path)?; + + let File_permission = if Task_user == File_user { + File_permissions.Get_user() + } else if self.User_manager.Is_in_group(Task_user, File_group) { + File_permissions.Get_group() } else { - Permissions.Get_others() + File_permissions.Get_others() }; - if !Flags.Is_permission_granted(&Permission) { + Ok(File_permission) + } + + fn Check_permission( + &self, + File_system: &dyn File_system_traits, + Task_identifier: Task_identifier_type, + Relative_path: impl AsRef, + Permission: Permission_type, + ) -> Result_type<()> { + let File_permission = self.Get_permission(File_system, Task_identifier, Relative_path)?; + + if !File_permission.Include(Permission) { return Err(Error_type::Permission_denied); } @@ -188,22 +282,13 @@ impl Virtual_file_system_type { pub fn Close(&self, File: Unique_file_identifier_type) -> Result_type<()> { let (File_system_identifier, File_identifier) = File.Split(); - if File_system_identifier == Self::Pipe_file_system_identifier { - return self.Pipes_file_system.write()?.Close( - self.Task_manager.Get_current_task_identifier()?, - File_identifier, - ); - } + let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)?; // Get the file system - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - File_system.Inner.Close(Task_identifier, File_identifier) + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? + .Inner + .Close(Task_identifier, File_identifier) } pub fn Read( @@ -213,23 +298,11 @@ impl Virtual_file_system_type { ) -> Result_type { let (File_system_identifier, File_identifier) = File_identifier.Split(); - if File_system_identifier == Self::Pipe_file_system_identifier { - return self.Pipes_file_system.write()?.Read( - self.Task_manager.Get_current_task_identifier()?, - File_identifier, - Buffer, - ); - } - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)?; // Get the file system - - File_system + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? .Inner .Read(Task_identifier, File_identifier, Buffer) } @@ -241,23 +314,11 @@ impl Virtual_file_system_type { ) -> Result_type { let (File_system_identifier, File_identifier) = File.Split(); - if File_system_identifier == Self::Pipe_file_system_identifier { - return self.Pipes_file_system.write()?.Write( - self.Task_manager.Get_current_task_identifier()?, - File_identifier, - Buffer, - ); - } - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)?; - - File_system + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? .Inner .Write(Task_identifier, File_identifier, Buffer) } @@ -273,96 +334,46 @@ impl Virtual_file_system_type { let File_systems = self.File_systems.read()?; // Get the file systems - let (File_system_identifier, File_identifier) = File_identifier.Split(); - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)?; // Get the file system - - File_system + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? .Inner .Set_position(Task_identifier, File_identifier, Position) } - pub fn Exists(&self, Path: impl AsRef) -> Result { - let File_systems = self.File_systems.read()?; // Get the file systems - - if File_systems.is_empty() { - return Ok(false); + pub fn Exists(&self, Path: impl AsRef) -> Result_type { + match self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Exists(&Relative_path) + }) { + Ok(Exists) => Ok(Exists), + Err(Error_type::Not_found) => Ok(false), + Err(Error) => Err(Error), } - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; // Get the file system - - File_system.Inner.Exists(&Relative_path) } - pub fn Get_size(&self, Path: impl AsRef) -> Result { - let File_systems = self.File_systems.read()?; // Get the file system - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; // Get the file system - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - File_system.Inner.Get_size(Task_identifier, &Relative_path) + pub fn Get_size(&self, Path: impl AsRef) -> Result_type { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Get_size(&Relative_path) + }) } - pub fn Get_type(&self, Path: impl AsRef) -> Result { - let File_systems = self.File_systems.read()?; // Get the file systems - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - File_system.Inner.Get_type(Task_identifier, &Relative_path) + pub fn Get_type(&self, Path: impl AsRef) -> Result_type { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Get_type(&Relative_path) + }) } - pub fn Get_permissions(&self, Path: impl AsRef) -> Result { - if Path.as_ref().Is_root() { - return Ok(Permissions_type::New_all_full()); - } - - let File_systems = self.File_systems.read()?; // Get the file systems - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - File_system - .Inner - .Get_permissions(Task_identifier, &Relative_path) + pub fn Get_permissions(&self, Path: impl AsRef) -> Result_type { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Get_permissions(&Relative_path) + }) } pub fn Get_owner( &self, Path: impl AsRef, - ) -> Result<(User_identifier_type, Group_identifier_type)> { - let File_systems = self.File_systems.read()?; // Get the file systems - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - File_system.Inner.Get_owner(Task_identifier, &Relative_path) + ) -> Result_type<(User_identifier_type, Group_identifier_type)> { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Get_owner(&Relative_path) + }) } pub fn Set_owner( @@ -370,146 +381,122 @@ impl Virtual_file_system_type { Path: impl AsRef, User: Option, Group: Option, - ) -> Result<()> { - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - let Task_user = self.Task_manager.Get_owner(Task_identifier)?; - - if !Manager_type::Is_root(Task_user) { - return Err(Error_type::Permission_denied); - } - - let File_systems = self.File_systems.read()?; - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_systems = self.File_systems.read()?; // Get the file systems - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - File_system - .Inner - .Set_owner(Task_identifier, &Relative_path, User, Group) + ) -> Result_type<()> { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system.Inner.Set_owner(&Relative_path, User, Group) + }) } pub fn Set_permissions( &self, Path: impl AsRef, - Permissions: &Permissions_type, - ) -> Result<()> { - if Path.as_ref().Is_root() { - return Err(Error_type::Permission_denied); - } - - let File_systems = self.File_systems.read()?; - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_systems = self.File_systems.read()?; // Get the file systems - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - // - Check permissions - - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - - let Task_user = self.Task_manager.Get_owner(Task_identifier)?; - - let Owner = if Manager_type::Is_root(Task_user) { - true - } else { - let (Owner_user, _) = File_system + Permissions: Permissions_type, + ) -> Result_type<()> { + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + File_system .Inner - .Get_owner(Task_identifier, &Relative_path)?; - - Task_user == Owner_user - }; - - if !Owner { - return Err(Error_type::Permission_denied); - } - - File_system - .Inner - .Set_permissions(Task_identifier, Permissions, &Relative_path) + .Set_permissions(&Relative_path, Permissions) + }) } - pub fn Close_all(&self, Task_identifier: Task_identifier_type) -> Result<()> { + pub fn Close_all(&self, Task_identifier: Task_identifier_type) -> Result_type<()> { let File_systems = self.File_systems.read()?; // Get the file systems for File_system in File_systems.values() { File_system.Inner.Close_all(Task_identifier)?; } - self.Pipes_file_system.write()?.Close_all(Task_identifier)?; - Ok(()) } - pub fn Create_named_pipe(&self, Path: &impl AsRef, Size: usize) -> Result<()> { - let Path = Path - .as_ref() - .Set_extension(Self::Named_pipe_extension) - .ok_or(Error_type::Invalid_path)?; // Append the pipe extension + pub fn Add_device( + &self, + Path: impl AsRef, + Device: Box, + ) -> Result_type<()> { + let File_systems = self.File_systems.read()?; // Get the file systems + + let File_system = Self::Get_file_system_from_identifier( + &File_systems, + Self::Device_file_system_identifier, + )?; + + File_system.Inner.Add_device(&Path, Device) + } - self.Create_file(&Path)?; // Create the special file + pub fn Create_named_pipe( + &self, + Path: &impl AsRef, + Size: Size_type, + ) -> Result_type<()> { + let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - let File = self.Open(&Path, Mode_type::Write_only().into())?; // Open the file + let mut File_systems = self.File_systems.write()?; // Get the file systems - let Pipe_identifier = self.Pipes_file_system.write()?.Create_named_pipe(Size)?; // Create the named pipe + let Parent_path = Path.as_ref().Go_parent().ok_or(Error_type::Invalid_path)?; - let Pipe_identifier: [u8; 4] = Pipe_identifier.into(); + let (_, File_system, Relative_path) = + Self::Get_file_system_from_mount_point(&File_systems, &Parent_path)?; // Get the file system identifier and the relative path - self.Write(File, &Pipe_identifier)?; // Write the pipe identifier + self.Check_permission( + File_system, + Task_identifier, + Relative_path, + Permission_type::New_write(), + )?; - Ok(()) + File_systems + .get_mut(&Self::Pipe_file_system_identifier) + .ok_or(Error_type::Invalid_path)? + .Inner + .Create_named_pipe(Path, Size) } pub fn Create_unnamed_pipe( &self, - Size: usize, + Size: Size_type, Status: Status_type, - ) -> Result<(Unique_file_identifier_type, Unique_file_identifier_type)> { + ) -> Result_type<(Unique_file_identifier_type, Unique_file_identifier_type)> { let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - let (File_identifier_read, File_identifier_write) = self - .Pipes_file_system + let (Read, Write) = self + .File_systems .write()? - .Create_unnamed_pipe(Task_identifier, Status, Size)?; // Create the unnamed pipe + .get_mut(&Self::Pipe_file_system_identifier) + .ok_or(Error_type::Invalid_path)? + .Inner + .Create_unnamed_pipe(Task_identifier, Size, Status)?; Ok(( - Unique_file_identifier_type::New( - Self::Pipe_file_system_identifier, - File_identifier_read, - ), - Unique_file_identifier_type::New( - Self::Pipe_file_system_identifier, - File_identifier_write, - ), + Unique_file_identifier_type::New(Self::Pipe_file_system_identifier, Read), + Unique_file_identifier_type::New(Self::Pipe_file_system_identifier, Write), )) } - pub fn Create_file(&self, Path: impl AsRef) -> Result<()> { + pub fn Create_file(&self, Path: impl AsRef) -> Result_type<()> { let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path + let (_, File_system, Relative_path) = + Self::Get_file_system_from_mount_point(&File_systems, &Path)?; // Get the file system identifier and the relative path - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; + // Check if the user has the right to create the file (write permission on the parent directory) + self.Check_permission( + File_system, + Task_identifier, + Relative_path.Go_parent().unwrap_or(Path_type::Get_root()), + Permission_type::New_write(), + )?; - File_system - .Inner - .Create_file(Task_identifier, &Relative_path) + File_system.Create_file(&Relative_path) } - pub fn Create_directory(&self, Path: impl AsRef, Recursive: bool) -> Result<()> { + pub fn Create_directory( + &self, + Path: impl AsRef, + Recursive: bool, + ) -> Result_type<()> { if Recursive { // If the directory already exists, return Ok(()) (only if recursive is true). if self.Exists(Path.as_ref())? { @@ -524,19 +511,22 @@ impl Virtual_file_system_type { } // Create current directory. - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - let File_systems = self.File_systems.read()?; // Get the file systems - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path + let (_, File_system, Relative_path) = + Self::Get_file_system_from_mount_point(&File_systems, &Path)?; - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; + let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - File_system - .Inner - .Create_directory(Task_identifier, &Relative_path) + // Check if the user has the right to create the directory (write permission and execute permission on the parent directory) + self.Check_permission( + File_system, + Task_identifier, + Relative_path, + Permission_type::New_write_execute(), + )?; + + File_system.Create_directory(&Relative_path) } pub fn Delete(&self, Path: impl AsRef, Recursive: bool) -> Result_type<()> { @@ -544,26 +534,23 @@ impl Virtual_file_system_type { todo!() } - // Delete current directory. + // Delete current directory / file. let Task_identifier = self.Task_manager.Get_current_task_identifier()?; - let File_systems = self.File_systems.read()?; // Get the file systems - - let (File_system_identifier, Relative_path) = Self::Get_file_system(&File_systems, &Path)?; // Get the file system identifier and the relative path - - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_path)?; - - // Check if the user has the right to delete the file (write permission on the parent directory) - self.Check_permissions( - File_system, - Task_identifier, - Relative_path.Go_parent().ok_or(Error_type::Invalid_path)?, - Mode_type::Write_only().into(), - )?; - - File_system.Inner.Delete(&Relative_path) + self.Try_on_concerned_file_systems(Path.as_ref(), |_, File_system, Relative_path| { + // Check if the user has the right to delete the file (write permission on the parent directory) + self.Check_permission( + &*File_system.Inner, + Task_identifier, + Relative_path.Go_parent().ok_or(Error_type::Invalid_path)?, + Permission_type::New_write(), + ) + })?; + + self.Try_on_concerned_file_systems(Path, |_, File_system, Relative_path| { + // Delete the file + File_system.Inner.Delete(&Relative_path) + }) } pub fn Transfert_file( @@ -571,25 +558,16 @@ impl Virtual_file_system_type { File: Unique_file_identifier_type, New_task: Task_identifier_type, ) -> Result_type { + let (File_system_identifier, File_identifier) = File.Split(); + let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let (File_system_identifier, File_identifier) = File.Split(); - - let New_file_identifier = if File_system_identifier == Self::Pipe_file_system_identifier { - self.Pipes_file_system.write()?.Transfert_file_identifier( - Task_identifier, - New_task, - File_identifier, - )? - } else { - File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)? + let New_file_identifier = + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? .Inner - .Transfert_file_identifier(Task_identifier, New_task, File_identifier)? - }; + .Transfert_file_identifier(Task_identifier, New_task, File_identifier)?; Ok(Unique_file_identifier_type::New( File_system_identifier, @@ -600,19 +578,12 @@ impl Virtual_file_system_type { pub fn Flush(&self, File: Unique_file_identifier_type) -> Result_type<()> { let (File_system_identifier, File_identifier) = File.Split(); - if File_system_identifier == Self::Pipe_file_system_identifier { - return Ok(()); // No need to flush a pipe. - // ? : Maybe we should return an error. - } - let Task_identifier = self.Task_manager.Get_current_task_identifier()?; let File_systems = self.File_systems.read()?; // Get the file systems - let File_system = File_systems - .get(&File_system_identifier) - .ok_or(Error_type::Invalid_identifier)?; // Get the file system - - File_system.Inner.Flush(Task_identifier, File_identifier) + Self::Get_file_system_from_identifier(&File_systems, File_system_identifier)? + .Inner + .Flush(Task_identifier, File_identifier) } } From fcb48b002a36aa0bcf80290002d44096e7cfcc8c Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:38:54 -0400 Subject: [PATCH 28/39] Use static mut for Virtual file system singleton instead of Arc (more efficient) --- Modules/File_system/src/Generics/Error.rs | 2 + Modules/File_system/src/Generics/File.rs | 14 +++---- .../src/Generics/Virtual_file_system.rs | 40 ++++++++++++++++++- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Modules/File_system/src/Generics/Error.rs b/Modules/File_system/src/Generics/Error.rs index 07fc3cf..2b5605e 100644 --- a/Modules/File_system/src/Generics/Error.rs +++ b/Modules/File_system/src/Generics/Error.rs @@ -26,6 +26,8 @@ pub enum Error_type { Invalid_mode, Unsupported_operation, Ressource_busy, + Already_initialized, + Not_initialized, Other, } diff --git a/Modules/File_system/src/Generics/File.rs b/Modules/File_system/src/Generics/File.rs index 817881d..caee590 100644 --- a/Modules/File_system/src/Generics/File.rs +++ b/Modules/File_system/src/Generics/File.rs @@ -33,7 +33,7 @@ impl Debug for File_type { impl File_type { pub fn Open( - File_system: &Virtual_file_system_type, + File_system: &'static Virtual_file_system_type, Path: impl AsRef, Flags: Flags_type, ) -> Result_type { @@ -41,13 +41,13 @@ impl File_type { Ok(File_type { File_identifier, - File_system: File_system.clone(), + File_system, }) } - pub fn Create_unamed_pipe( - File_system: &Virtual_file_system_type, - Size: usize, + pub fn Create_unnamed_pipe( + File_system: &'static Virtual_file_system_type, + Size: Size_type, Status: Status_type, ) -> Result_type<(Self, Self)> { let (File_identifier_read, File_identifier_write) = @@ -56,11 +56,11 @@ impl File_type { Ok(( File_type { File_identifier: File_identifier_read, - File_system: File_system.clone(), + File_system, }, File_type { File_identifier: File_identifier_write, - File_system: File_system.clone(), + File_system, }, )) } diff --git a/Modules/File_system/src/Generics/Virtual_file_system.rs b/Modules/File_system/src/Generics/Virtual_file_system.rs index e754432..6d0d49a 100644 --- a/Modules/File_system/src/Generics/Virtual_file_system.rs +++ b/Modules/File_system/src/Generics/Virtual_file_system.rs @@ -14,7 +14,45 @@ struct Internal_file_system_type { pub Inner: Box, } -#[derive(Clone)] +/// Instance of the virtual file system. +/// +/// # Safety +/// I know, it is not safe to use mutable static variables. +/// It is thread safe (after initialization) because it is only read after initialization. +/// It is a pragmatic choice for efficiency in embedded systems contexts (avoid using Arc). +static mut Virtual_file_system_instance: Option = None; + +pub fn Initialize( + Task_manager: Task::Manager_type, + User_manager: Users::Manager_type, +) -> Result_type<&'static Virtual_file_system_type> { + unsafe { + if Is_initialized() { + return Err(Error_type::Already_initialized); + } + + Virtual_file_system_instance + .replace(Virtual_file_system_type::New(Task_manager, User_manager)?); + + Get_instance() + } +} + +pub fn Is_initialized() -> bool { + unsafe { Virtual_file_system_instance.is_some() } +} + +pub fn Get_instance() -> Result_type<&'static Virtual_file_system_type> { + unsafe { + Virtual_file_system_instance + .as_ref() + .ok_or(Error_type::Not_initialized) + } +} + +/// The virtual file system. +/// +/// It is a singleton. pub struct Virtual_file_system_type { /// A reference to the task manager. Task_manager: Task::Manager_type, From e50bc5ccefbb681357e2813547948b96b6e09178 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:39:32 -0400 Subject: [PATCH 29/39] Export all generics to the root of File system --- Modules/File_system/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/File_system/src/lib.rs b/Modules/File_system/src/lib.rs index 8831abe..5bb70f6 100644 --- a/Modules/File_system/src/lib.rs +++ b/Modules/File_system/src/lib.rs @@ -2,7 +2,8 @@ #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] -pub mod Generics; +mod Generics; +pub use Generics::*; pub mod Drivers; From e858e1f1d56f7ada3667c34ba82d91af9168c2bb Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:40:11 -0400 Subject: [PATCH 30/39] Update Virtual file system integration test --- .../File_system/Tests/Virtual_file_system.rs | 109 +++++++++++++++--- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/Modules/File_system/Tests/Virtual_file_system.rs b/Modules/File_system/Tests/Virtual_file_system.rs index ea1763a..8960550 100644 --- a/Modules/File_system/Tests/Virtual_file_system.rs +++ b/Modules/File_system/Tests/Virtual_file_system.rs @@ -1,20 +1,22 @@ #![allow(non_snake_case)] +#![allow(non_camel_case_types)] #[cfg(target_os = "linux")] #[test] -fn Virtual_file_system_test() { +fn Test_virtual_file_system_file() { + use std::sync::RwLock; + use File_system::{ Drivers::Native::File_system_type, - Prelude::{ - File_type, Mode_type, Path_type, Position_type, Status_type, Virtual_file_system_type, - }, + Prelude::{Device_trait, File_type, Mode_type, Path_type, Position_type, Status_type}, }; let Task_manager = Task::Manager_type::New(); let Users_manager = Users::Manager_type::New(); - let Virtual_file_system = Virtual_file_system_type::New(Task_manager, Users_manager); + let Virtual_file_system = File_system::Initialize(Task_manager, Users_manager) + .expect("Failed to initialize file system"); Virtual_file_system .Mount( @@ -39,7 +41,7 @@ fn Virtual_file_system_test() { .expect("Failed to create file"); let File = File_type::Open( - &Virtual_file_system, + Virtual_file_system, File_path, Mode_type::Read_write().into(), ) @@ -49,7 +51,7 @@ fn Virtual_file_system_test() { File.Write(Data).expect("Failed to write data"); - File.Set_position(&Position_type::Start(0_u64.into())) + File.Set_position(&Position_type::Start(0)) .expect("Failed to set position"); let mut Buffer = [0; 13]; @@ -64,9 +66,12 @@ fn Virtual_file_system_test() { .Delete(File_path, false) .expect("Failed to delete file"); - let (Pipe_read, Pipe_write) = - File_type::Create_unamed_pipe(&Virtual_file_system, 512, Status_type::default()) - .expect("Failed to create pipe"); + let (Pipe_read, Pipe_write) = File_type::Create_unnamed_pipe( + Virtual_file_system, + 512_usize.into(), + Status_type::default(), + ) + .expect("Failed to create pipe"); Pipe_write.Write(Data).expect("Failed to write data"); @@ -87,16 +92,23 @@ fn Virtual_file_system_test() { .expect("Failed to delete pipe"); } - /* Virtual_file_system - .Create_named_pipe(&Pipe_path, 512) + .Create_named_pipe(&Pipe_path, 512_usize.into()) .expect("Failed to create pipe"); let Pipe_read = File_type::Open( - &Virtual_file_system, + Virtual_file_system, Pipe_path, Mode_type::Read_only().into(), - ).expect("Failed to open pipe"); + ) + .expect("Failed to open pipe"); + + let Pipe_write = File_type::Open( + Virtual_file_system, + Pipe_path, + Mode_type::Write_only().into(), + ) + .expect("Failed to open pipe"); let mut Buffer = [0; 13]; @@ -112,5 +124,72 @@ fn Virtual_file_system_test() { Virtual_file_system .Delete(Pipe_path, false) .expect("Failed to delete pipe"); - */ + + struct Dummy_device_type(RwLock); + + impl Device_trait for Dummy_device_type { + fn Read(&self, Buffer: &mut [u8]) -> File_system::Prelude::Result_type { + Buffer.copy_from_slice(&self.0.read()?.to_le_bytes()); + + Ok(std::mem::size_of::()) + } + + fn Write(&self, Buffer: &[u8]) -> File_system::Prelude::Result_type { + *self.0.write()? = u64::from_le_bytes(Buffer.try_into().unwrap()); + + Ok(std::mem::size_of::()) + } + + fn Get_size(&self) -> File_system::Prelude::Result_type { + Ok(std::mem::size_of::()) + } + + fn Set_position( + &self, + _: &File_system::Prelude::Position_type, + ) -> File_system::Prelude::Result_type { + Ok(0) + } + + fn Flush(&self) -> File_system::Prelude::Result_type<()> { + Ok(()) + } + } + + let Device = Dummy_device_type(RwLock::new(0)); + + let Device_path = Path_type::New("/Device").expect("Failed to create path"); + + Virtual_file_system + .Add_device(Device_path, Box::new(Device)) + .expect("Failed to add device"); + + let Device_file = File_type::Open( + Virtual_file_system, + Device_path, + Mode_type::Read_write().into(), + ) + .expect("Failed to open device"); + + let Data = 0x1234567890ABCDEF_u64; + + Device_file + .Write(&Data.to_le_bytes()) + .expect("Failed to write data"); + + Device_file + .Set_position(&Position_type::Start(0)) + .expect("Failed to set position"); + + let mut Buffer = [0; 8]; + + Device_file.Read(&mut Buffer).expect("Failed to read data"); + + assert_eq!(Buffer, Data.to_le_bytes()); + + std::mem::drop(Device_file); + + Virtual_file_system + .Delete(Device_path, false) + .expect("Failed to delete device"); } From d8f0344b61d6c96916caede35c5ed720d08e276d Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:41:34 -0400 Subject: [PATCH 31/39] Update native screen drivers to use new device file type instead of regular Screen trait --- Modules/Screen/Cargo.toml | 1 + Modules/Screen/src/Drivers/SDL2/mod.rs | 170 ++++++++++++++++++------- 2 files changed, 123 insertions(+), 48 deletions(-) diff --git a/Modules/Screen/Cargo.toml b/Modules/Screen/Cargo.toml index 827929e..f91ee24 100644 --- a/Modules/Screen/Cargo.toml +++ b/Modules/Screen/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +File_system = { path = "../File_system" } [target.'cfg( target_os = "espidf" )'.dependencies] embedded-graphics = "0.8" diff --git a/Modules/Screen/src/Drivers/SDL2/mod.rs b/Modules/Screen/src/Drivers/SDL2/mod.rs index 85bc16b..511cdc0 100644 --- a/Modules/Screen/src/Drivers/SDL2/mod.rs +++ b/Modules/Screen/src/Drivers/SDL2/mod.rs @@ -1,6 +1,6 @@ use crate::{ Generics, - Prelude::{Error_type, Result_type}, + Prelude::{Area_type, Color_ARGB8888_type, Error_type, Result_type}, }; use sdl2::{ @@ -9,12 +9,9 @@ use sdl2::{ video::{self, WindowBuildError}, EventPump, IntegerOrSdlError, }; +use File_system::Prelude::Device_trait; -use std::{ - cell::RefCell, - process::exit, - sync::{Arc, RwLock}, -}; +use std::{mem::size_of, process::exit, sync::RwLock}; impl From for Error_type { fn from(Value: String) -> Self { @@ -51,55 +48,72 @@ impl Screen_type { Ok(Self(Canvas)) } + + pub fn Get_resolution(&self) -> Result_type { + Ok(self + .0 + .output_size() + .map(|(Width, Height)| Generics::Point_type::New(Width as i16, Height as i16))?) + } } -impl Generics::Screen_traits for Screen_type { - fn Update(&mut self, Refresh_area: &Generics::Refresh_area_type) { - let mut Buffer_iterator = Refresh_area.Buffer.iter(); +impl Generics::Screen_traits for Screen_type { + fn Update(&mut self, Area: Area_type, Buffer: &[Generics::Color_type]) -> Result_type<()> { + let mut Buffer_iterator = Buffer.iter(); + + let Point_1 = Area.Get_point_1(); + let Point_2 = Area.Get_point_2(); + + for Y in Point_1.Get_y() as i32..=Point_2.Get_y() as i32 { + for X in Point_1.Get_x() as i32..=Point_2.Get_x() as i32 { + let Color = Buffer_iterator + .next() + .ok_or(Error_type::Invalid_dimension)?; - for Y in 0..=Refresh_area.Area.Size.Y { - for X in 0..=Refresh_area.Area.Size.X { - let Color = Buffer_iterator.next().unwrap(); + #[cfg(not(feature = "ARGB8888"))] + let Color: Color_ARGB8888_type = (*Color).into(); - self.0 - .set_draw_color(pixels::Color::RGB(Color.Red, Color.Green, Color.Blue)); - let _ = self.0.draw_point(sdl2::rect::Point::new( - (X + Refresh_area.Area.Position.X) as i32, - (Y + Refresh_area.Area.Position.Y) as i32, + self.0.set_draw_color(pixels::Color::RGB( + Color.Get_red(), + Color.Get_green(), + Color.Get_blue(), )); + + let _ = self.0.draw_point(sdl2::rect::Point::new(X, Y)); } } self.0.present(); - } - fn Get_resolution(&self) -> Result_type { - Ok(self - .0 - .output_size() - .map(|(Width, Height)| Generics::Point_type::New(Width as i16, Height as i16))?) + Ok(()) } } -pub struct Pointer_type { +pub struct Pointer_device_type { Window_identifier: u32, - Event_pump: RefCell, - Last_input: Arc>, + Event_pump: RwLock, + Last_input: RwLock<(Generics::Point_type, Generics::Touch_type)>, } -impl Pointer_type { +unsafe impl Send for Pointer_device_type {} + +unsafe impl Sync for Pointer_device_type {} + +impl Pointer_device_type { pub fn New(Window_identifier: u32, Event_pump: EventPump) -> Self { Self { Window_identifier, - Event_pump: RefCell::new(Event_pump), - Last_input: Arc::new(RwLock::new(( + Event_pump: RwLock::new(Event_pump), + Last_input: RwLock::new(( Generics::Point_type::New(0, 0), Generics::Touch_type::Released, - ))), + )), } } - pub fn Update(&mut self) { - for Event in self.Event_pump.borrow_mut().poll_iter() { + pub fn Update(&self) -> Result_type<()> { + let mut Last_input = self.Last_input.write()?; + + for Event in self.Event_pump.write()?.poll_iter() { match Event { event::Event::Quit { .. } => exit(0), event::Event::MouseButtonDown { @@ -114,10 +128,9 @@ impl Pointer_type { if (window_id == self.Window_identifier) && (mouse_btn == mouse::MouseButton::Left) { - let mut Last_input = self.Last_input.write().unwrap(); + Last_input.0 = Last_input.0.Set(x as i16, y as i16); + Last_input.0 = Last_input.0.Set(x as i16, y as i16); - Last_input.0.X = x as i16; - Last_input.0.Y = y as i16; Last_input.1 = Generics::Touch_type::Pressed; } } @@ -132,8 +145,6 @@ impl Pointer_type { if (window_id == self.Window_identifier) && (mouse_btn == mouse::MouseButton::Left) { - let mut Last_input = self.Last_input.write().unwrap(); - Last_input.1 = Generics::Touch_type::Released; } } @@ -147,37 +158,67 @@ impl Pointer_type { .. } => { if (window_id == self.Window_identifier) && (mousestate.left()) { - let mut Last_input = self.Last_input.write().unwrap(); - - Last_input.0.X = x as i16; - Last_input.0.Y = y as i16; + Last_input.0 = Last_input.0.Set(x as i16, y as i16); } } _ => {} }; } + + Ok(()) } } -impl Generics::Input_traits for Pointer_type { - fn Get_latest_input(&self) -> (Generics::Point_type, Generics::Touch_type) { - *self.Last_input.read().unwrap() +impl Device_trait for Pointer_device_type { + fn Read(&self, Buffer: &mut [u8]) -> File_system::Prelude::Result_type { + if self.Update().is_err() { + return Err(File_system::Prelude::Error_type::Internal_error); + } + + let Last_input = self.Last_input.read()?; + + Buffer[0..2].copy_from_slice(&Last_input.0.Get_x().to_le_bytes()); + Buffer[2..4].copy_from_slice(&Last_input.0.Get_y().to_le_bytes()); + Buffer[4] = Last_input.1.into(); + + Ok(5) + } + + fn Write(&self, _: &[u8]) -> File_system::Prelude::Result_type { + Err(File_system::Prelude::Error_type::Unsupported_operation) + } + + fn Get_size(&self) -> File_system::Prelude::Result_type { + Ok(size_of::()) + } + + fn Set_position( + &self, + _: &File_system::Prelude::Position_type, + ) -> File_system::Prelude::Result_type { + Err(File_system::Prelude::Error_type::Unsupported_operation) + } + + fn Flush(&self) -> File_system::Prelude::Result_type<()> { + Ok(()) } } -pub fn New_touchscreen(Size: Generics::Point_type) -> Result_type<(Screen_type, Pointer_type)> { +pub fn New_touchscreen( + Size: Generics::Point_type, +) -> Result_type<(Screen_type, Pointer_device_type)> { let Context = sdl2::init()?; let Video_subsystem = Context.video()?; let Window = Video_subsystem - .window("Xila", Size.X as u32, Size.Y as u32) + .window("Xila", Size.Get_x() as u32, Size.Get_y() as u32) .position_centered() .build()?; let Event_pump = Context.event_pump()?; - let Pointer = Pointer_type::New(Window.id(), Event_pump); + let Pointer = Pointer_device_type::New(Window.id(), Event_pump); let Screen = Screen_type::New(Window)?; @@ -186,6 +227,8 @@ pub fn New_touchscreen(Size: Generics::Point_type) -> Result_type<(Screen_type, #[cfg(test)] mod tests { + use Generics::Screen_traits; + use super::*; #[test] @@ -200,7 +243,38 @@ mod tests { assert!(Touchscreen.is_ok()); - let (_, _) = Touchscreen.unwrap(); + let (mut Screen, Pointer_device_type) = + Touchscreen.expect("Touchscreen initialization failed."); + + let mut Buffer = [0; 5]; + + assert_eq!(Pointer_device_type.Read(&mut Buffer), Ok(5)); + + Screen + .Update( + Area_type::New( + Generics::Point_type::New(0, 0), + Generics::Point_type::New(9, 9), + ), + &[Generics::Color_type::New(255, 255, 255); 100], + ) + .expect("Screen update failed."); + + assert_eq!( + Screen.Update( + Area_type::New( + Generics::Point_type::New(0, 0), + Generics::Point_type::New(10, 9), + ), + &[Generics::Color_type::New(255, 255, 255); 100], + ), + Err(Error_type::Invalid_dimension) + ); + + assert_eq!( + Screen.Get_resolution().unwrap(), + Generics::Point_type::New(800, 480) + ); unsafe { sdl2::sys::SDL_Quit(); // Force SDL2 to quit to avoid conflicts with other tests. From f6a36e89e529cbeb39d073330ac15c19c130bdaf Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:41:43 -0400 Subject: [PATCH 32/39] Update SDL2 in Screen --- Modules/Screen/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Screen/Cargo.toml b/Modules/Screen/Cargo.toml index f91ee24..f0efd5d 100644 --- a/Modules/Screen/Cargo.toml +++ b/Modules/Screen/Cargo.toml @@ -10,5 +10,5 @@ File_system = { path = "../File_system" } embedded-graphics = "0.8" [target.'cfg( target_arch = "x86_64" )'.dependencies] -sdl2 = { version = "0.36", features = [] } +sdl2 = { version = "0.37.0", features = [] } embedded-graphics = "0.8" \ No newline at end of file From c2b7a6418ac588c88037a052fdcd10f6485fc164 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:43:19 -0400 Subject: [PATCH 33/39] Remove unused traits and types, move the remaining into their own files and implement properly different color format --- Modules/Screen/Cargo.toml | 7 +- Modules/Screen/src/Generics/Area.rs | 36 ++++ Modules/Screen/src/Generics/Color.rs | 238 +++++++++++++++++++++++++++ Modules/Screen/src/Generics/Point.rs | 41 +++++ Modules/Screen/src/Generics/mod.rs | 66 +++----- 5 files changed, 347 insertions(+), 41 deletions(-) create mode 100644 Modules/Screen/src/Generics/Area.rs create mode 100644 Modules/Screen/src/Generics/Color.rs create mode 100644 Modules/Screen/src/Generics/Point.rs diff --git a/Modules/Screen/Cargo.toml b/Modules/Screen/Cargo.toml index f0efd5d..9d40d3d 100644 --- a/Modules/Screen/Cargo.toml +++ b/Modules/Screen/Cargo.toml @@ -11,4 +11,9 @@ embedded-graphics = "0.8" [target.'cfg( target_arch = "x86_64" )'.dependencies] sdl2 = { version = "0.37.0", features = [] } -embedded-graphics = "0.8" \ No newline at end of file +embedded-graphics = "0.8" + +[features] +default = ["RGB565"] +RGB565 = [] +ARGB8888 = [] diff --git a/Modules/Screen/src/Generics/Area.rs b/Modules/Screen/src/Generics/Area.rs new file mode 100644 index 0000000..8115b04 --- /dev/null +++ b/Modules/Screen/src/Generics/Area.rs @@ -0,0 +1,36 @@ +use super::Point_type; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Area_type(Point_type, Point_type); + +impl Area_type { + pub fn New(Point_1: Point_type, Point_2: Point_type) -> Self { + Self(Point_1, Point_2) + } + + pub fn Get_point_1(&self) -> Point_type { + self.0 + } + + pub fn Get_point_2(&self) -> Point_type { + self.1 + } + + pub fn Get_width(&self) -> i16 { + self.1.Get_x() - self.0.Get_x() + } + + pub fn Get_height(&self) -> i16 { + self.1.Get_y() - self.0.Get_y() + } + + pub fn Set_point_1(mut self, Value: Point_type) -> Self { + self.0 = Value; + self + } + + pub fn Set_point_2(mut self, Value: Point_type) -> Self { + self.1 = Value; + self + } +} diff --git a/Modules/Screen/src/Generics/Color.rs b/Modules/Screen/src/Generics/Color.rs new file mode 100644 index 0000000..51f68fa --- /dev/null +++ b/Modules/Screen/src/Generics/Color.rs @@ -0,0 +1,238 @@ +#[cfg(feature = "RGB565")] +pub type Color_type = Color_RGB565_type; +#[cfg(feature = "ARGB8888")] +pub type Color_type = Color_ARGB8888_type; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(transparent)] +pub struct Color_RGB565_type(u16); + +impl Color_RGB565_type { + pub fn New(Red: u8, Green: u8, Blue: u8) -> Self { + Self(0).Set_red(Red).Set_green(Green).Set_blue(Blue) + } + + pub const fn Get_red(&self) -> u8 { + ((self.0 >> 11) & 0b11111) as u8 + } + + pub const fn Get_green(&self) -> u8 { + ((self.0 >> 5) & 0b111111) as u8 + } + + pub const fn Get_blue(&self) -> u8 { + (self.0 & 0b11111) as u8 + } + + pub fn Set_red(mut self, Value: u8) -> Self { + let Value = Value & 0b11111; // 5 bits + self.0 = (self.0 & !(0b11111 << 11)) | ((Value as u16) << 11); + self + } + + pub fn Set_green(mut self, Value: u8) -> Self { + let Value = Value & 0b111111; // 6 bits + self.0 = (self.0 & !(0b111111 << 5)) | ((Value as u16) << 5); + self + } + + pub fn Set_blue(mut self, Value: u8) -> Self { + let Value = Value & 0b11111; // 5 bits + self.0 = (self.0 & !0b11111) | (Value as u16); + self + } +} + +impl From for u16 { + fn from(Value: Color_RGB565_type) -> u16 { + Value.0 + } +} + +impl From for Color_RGB565_type { + fn from(Value: u16) -> Self { + Self(Value) + } +} + +impl From for Color_RGB565_type { + fn from(Value: Color_ARGB8888_type) -> Self { + Self::New( + Value.Get_red() >> 3, + Value.Get_green() >> 2, + Value.Get_blue() >> 3, + ) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(transparent)] +pub struct Color_ARGB8888_type(u32); + +impl Color_ARGB8888_type { + pub fn New(Alpha: u8, Red: u8, Green: u8, Blue: u8) -> Self { + Self(0) + .Set_alpha(Alpha) + .Set_red(Red) + .Set_green(Green) + .Set_blue(Blue) + } + + pub const fn Get_alpha(&self) -> u8 { + ((self.0 >> 24) & 0b1111_1111) as u8 + } + + pub const fn Get_red(&self) -> u8 { + ((self.0 >> 16) & 0b1111_1111) as u8 + } + + pub const fn Get_green(&self) -> u8 { + ((self.0 >> 8) & 0b1111_1111) as u8 + } + + pub const fn Get_blue(&self) -> u8 { + ((self.0) & 0b1111_1111) as u8 + } + + pub fn Set_alpha(mut self, Value: u8) -> Self { + self.0 = (self.0 & !(0b1111_1111 << 24)) | ((Value as u32) << 24); + self + } + + pub fn Set_red(mut self, Value: u8) -> Self { + self.0 = (self.0 & 0xFF00_FFFF) | ((Value as u32) << 16); + self + } + + pub fn Set_green(mut self, Value: u8) -> Self { + self.0 = (self.0 & 0xFFFF_00FF) | ((Value as u32) << 8); + self + } + + pub fn Set_blue(mut self, Value: u8) -> Self { + self.0 = (self.0 & 0xFFFF_FF00) | (Value as u32); + self + } +} + +impl From for u32 { + fn from(Value: Color_ARGB8888_type) -> u32 { + Value.0 + } +} + +impl From for Color_ARGB8888_type { + fn from(Value: u32) -> Self { + Self(Value) + } +} + +impl From for Color_ARGB8888_type { + fn from(Value: Color_RGB565_type) -> Self { + Self::New( + 0xFF, + Value.Get_red() << 3, + Value.Get_green() << 2, + Value.Get_blue() << 3, + ) + } +} + +#[cfg(test)] +mod Tests { + use super::*; + + #[test] + fn Test_RGB565() { + let Color = Color_RGB565_type::New(255, 255, 255); + assert_eq!(Color.Get_red(), 0b11111); + assert_eq!(Color.Get_green(), 0b111111); + assert_eq!(Color.Get_blue(), 0b11111); + assert_eq!(Color.0, 0xFFFF); + + let Color = Color_RGB565_type::New(255, 0, 0); + assert_eq!(Color.Get_red(), 0b11111); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0xF800); + + let Color = Color_RGB565_type::New(0, 255, 0); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0b111111); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0x07E0); + + let Color = Color_RGB565_type::New(0, 0, 255); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0b11111); + assert_eq!(Color.0, 0x00_1F); + + let Color = Color_RGB565_type::New(0, 0, 0); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0); + } + + #[test] + fn Test_ARGB8888() { + let Color = Color_ARGB8888_type::New(255, 255, 255, 255); + assert_eq!(Color.Get_alpha(), 0xFF); + assert_eq!(Color.Get_red(), 0xFF); + assert_eq!(Color.Get_green(), 0xFF); + assert_eq!(Color.Get_blue(), 0xFF); + assert_eq!(Color.0, 0xFFFF_FFFF); + + let Color = Color_ARGB8888_type::New(255, 0, 0, 0); + assert_eq!(Color.Get_alpha(), 0xFF); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0xFF00_0000); + + let Color = Color_ARGB8888_type::New(0, 255, 0, 0); + assert_eq!(Color.Get_alpha(), 0); + assert_eq!(Color.Get_red(), 0xFF); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0x00FF_0000); + + let Color = Color_ARGB8888_type::New(0, 0, 255, 0); + assert_eq!(Color.Get_alpha(), 0); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0xFF); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0x0000_FF00); + + let Color = Color_ARGB8888_type::New(0, 0, 0, 255); + assert_eq!(Color.Get_alpha(), 0); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0xFF); + assert_eq!(Color.0, 0x0000_00FF); + + let Color = Color_ARGB8888_type::New(0, 0, 0, 0); + assert_eq!(Color.Get_alpha(), 0); + assert_eq!(Color.Get_red(), 0); + assert_eq!(Color.Get_green(), 0); + assert_eq!(Color.Get_blue(), 0); + assert_eq!(Color.0, 0); + } + + #[test] + fn Test_Conversion() { + let Color = Color_RGB565_type::New(255, 255, 255); + let Color = Color_ARGB8888_type::from(Color); + assert_eq!(Color.Get_alpha(), 0xFF); + assert_eq!(Color.Get_red(), 248); + assert_eq!(Color.Get_green(), 252); + assert_eq!(Color.Get_blue(), 248); + + let Color = Color_ARGB8888_type::New(255, 255, 255, 255); + let Color = Color_RGB565_type::from(Color); + assert_eq!(Color.Get_red(), 0b11111); + assert_eq!(Color.Get_green(), 0b111111); + assert_eq!(Color.Get_blue(), 0b11111); + } +} diff --git a/Modules/Screen/src/Generics/Point.rs b/Modules/Screen/src/Generics/Point.rs new file mode 100644 index 0000000..ef294c3 --- /dev/null +++ b/Modules/Screen/src/Generics/Point.rs @@ -0,0 +1,41 @@ +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Point_type { + X: i16, + Y: i16, +} + +impl Point_type { + pub const fn New(X: i16, Y: i16) -> Self { + Self { X, Y } + } + + pub const fn Get_x(&self) -> i16 { + self.X + } + + pub const fn Get_y(&self) -> i16 { + self.Y + } + + pub fn Set_x(mut self, Value: i16) -> Self { + self.X = Value; + self + } + + pub fn Set_y(mut self, Value: i16) -> Self { + self.Y = Value; + self + } + + pub fn Set(mut self, X: i16, Y: i16) -> Self { + self.X = X; + self.Y = Y; + self + } + + pub fn Get_distance(&self, Other: Point_type) -> f32 { + let X = (self.X - Other.X) as f32; + let Y = (self.Y - Other.Y) as f32; + (X * X + Y * Y).sqrt() + } +} diff --git a/Modules/Screen/src/Generics/mod.rs b/Modules/Screen/src/Generics/mod.rs index 864d4cf..22b292d 100644 --- a/Modules/Screen/src/Generics/mod.rs +++ b/Modules/Screen/src/Generics/mod.rs @@ -1,52 +1,38 @@ +mod Area; +mod Color; mod Error; -pub use Error::*; - -#[derive(Clone, Copy)] -pub struct Point_type { - pub X: i16, - pub Y: i16, -} - -impl Point_type { - pub fn New(X: i16, Y: i16) -> Self { - Self { X, Y } - } -} - -pub struct Area_type { - pub Position: Point_type, - pub Size: Point_type, -} - -impl Area_type { - pub fn New(Position: Point_type, Size: Point_type) -> Self { - Self { Position, Size } - } -} - -#[derive(Clone, Copy)] -pub struct Color_type { - pub Red: u8, - pub Green: u8, - pub Blue: u8, -} +mod Point; -pub struct Refresh_area_type { - pub Area: Area_type, - pub Buffer: [Color_type; Buffer_size], -} +pub use Area::*; +pub use Color::*; +pub use Error::*; +pub use Point::*; -pub trait Screen_traits { - fn Update(&mut self, Refresh_area: &Refresh_area_type); - fn Get_resolution(&self) -> Result_type; +pub trait Screen_traits { + fn Update(&mut self, Area: Area_type, Buffer: &[Color_type]) -> Result_type<()>; } #[derive(Clone, Copy)] +#[repr(C)] pub enum Touch_type { Pressed, Released, } -pub trait Input_traits { - fn Get_latest_input(&self) -> (Point_type, Touch_type); +impl From for u8 { + fn from(Value: Touch_type) -> u8 { + Value as u8 + } +} + +impl TryFrom for Touch_type { + type Error = (); + + fn try_from(Value: u8) -> Result { + match Value { + 0 => Ok(Self::Pressed), + 1 => Ok(Self::Released), + _ => Err(()), + } + } } From 65c2b35cff0ee6e171cc95768a52896ebaa38b33 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:43:45 -0400 Subject: [PATCH 34/39] Refactor Error_type to include Poisoned_lock variant and implement From trait for PoisonError in Screen --- Modules/Screen/src/Generics/Error.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Modules/Screen/src/Generics/Error.rs b/Modules/Screen/src/Generics/Error.rs index 68f8f2c..ae97129 100644 --- a/Modules/Screen/src/Generics/Error.rs +++ b/Modules/Screen/src/Generics/Error.rs @@ -1,9 +1,18 @@ #![allow(non_camel_case_types)] +use std::sync::PoisonError; + pub type Result_type = std::result::Result; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Error_type { Invalid_dimension, + Poisoned_lock, Unknown(String), } + +impl From> for Error_type { + fn from(_: PoisonError) -> Self { + Error_type::Poisoned_lock + } +} From 5fd20ad45c7b02bf5144cf7ef547a545b931dc57 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:48:12 -0400 Subject: [PATCH 35/39] Refactor Graphics to use new Device file for Input_type, add Error_type and Result_type with necessary castings, add graphics manager and move types into their own file. --- Modules/Graphics/Cargo.toml | 14 ++++ Modules/Graphics/Tests/Graphics.rs | 81 +++++++++++++++++++++ Modules/Graphics/src/Display.rs | 84 ++++++++++----------- Modules/Graphics/src/Draw_buffer.rs | 16 ++++ Modules/Graphics/src/Error.rs | 46 ++++++++++++ Modules/Graphics/src/Input.rs | 109 +++++++++------------------- Modules/Graphics/src/Manager.rs | 53 ++++++++++++++ Modules/Graphics/src/lib.rs | 23 ++---- 8 files changed, 288 insertions(+), 138 deletions(-) create mode 100644 Modules/Graphics/Tests/Graphics.rs create mode 100644 Modules/Graphics/src/Draw_buffer.rs create mode 100644 Modules/Graphics/src/Error.rs create mode 100644 Modules/Graphics/src/Manager.rs diff --git a/Modules/Graphics/Cargo.toml b/Modules/Graphics/Cargo.toml index 87bff1a..6134bd2 100644 --- a/Modules/Graphics/Cargo.toml +++ b/Modules/Graphics/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] cstr_core = "0.2.6" Task = { path = "../Task" } +File_system = { version = "0.1.0", path = "../File_system" } [target.'cfg( target_os = "espidf" )'.dependencies] lvgl = { git = "https://github.com/lvgl/lv_binding_rust.git", default-features = false, features = [ @@ -23,3 +24,16 @@ lvgl = { git = "https://github.com/lvgl/lv_binding_rust.git", features = [ embedded-graphics = "0.8.1" Screen = { path = "../Screen" } Shared = { path = "../Shared" } + +[dev-dependencies] +Users = { path = "../Users" } +Task = { path = "../Task" } + +[features] +default = ["RGB565"] +RGB565 = ["Screen/RGB565"] +ARGB8888 = ["Screen/ARGB8888"] + +[[test]] +name = "Graphics" +path = "Tests/Graphics.rs" \ No newline at end of file diff --git a/Modules/Graphics/Tests/Graphics.rs b/Modules/Graphics/Tests/Graphics.rs new file mode 100644 index 0000000..6089453 --- /dev/null +++ b/Modules/Graphics/Tests/Graphics.rs @@ -0,0 +1,81 @@ +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +use lvgl::Widget; +use std::{ + thread::sleep, + time::{Duration, Instant}, +}; +use File_system::Prelude::{File_type, Mode_type, Path_type, Virtual_file_system_type}; +use Screen::{Drivers::SDL2::New_touchscreen, Prelude::Point_type}; + +#[cfg(target_os = "linux")] +#[test] +#[ignore] +fn main() { + lvgl::init(); + + const Horizontal_resolution: u32 = 800; + const Vertical_resolution: u32 = 480; + const Buffer_size: usize = (Horizontal_resolution * Vertical_resolution / 2) as usize; + + let (S, Pointer) = New_touchscreen(Point_type::New( + Horizontal_resolution as i16, + Vertical_resolution as i16, + )) + .expect("Error creating touchscreen"); + + let S = Box::new(S); + + let Users_manager = Users::Manager_type::New(); + + let Task_manager = Task::Manager_type::New(); + + let Virtual_file_system = File_system::Initialize(Task_manager, Users_manager) + .expect("Error initializing file system"); + + let Pointer_device_path = Path_type::New("/Device/Pointer").expect("Error creating path"); + + Virtual_file_system + .Add_device(Pointer_device_path, Box::new(Pointer)) + .expect("Error adding pointer device"); + + let Pointer_file = File_type::Open( + Virtual_file_system, + Pointer_device_path, + Mode_type::Read_only().into(), + ) + .expect("Error opening pointer file"); + + Graphics::Initialize().expect("Error initializing manager"); + + let Graphics_manager = Graphics::Get_instance().expect("Error getting manager"); + + let Resolution = S.Get_resolution().expect("Error getting resolution"); + + let Display = Graphics_manager + .Create_display::(S, Resolution, Pointer_file) + .expect("Error adding screen"); + + let mut S = Display.Get_object().expect("Error getting screen"); + + let _ = lvgl::widgets::Slider::create(&mut S); + + let Calendar = lvgl::widgets::Calendar::create(&mut S); + assert!(Calendar.is_ok()); + let mut Calendar = Calendar.unwrap(); + + let mut Style = lvgl::style::Style::default(); + Style.set_bg_color(lvgl::Color::from_rgb((255, 0, 0))); + + let _ = Calendar.add_style(lvgl::obj::Part::Any, &mut Style); + let _ = Calendar.set_align(lvgl::Align::Center, 0, 0); + + loop { + let Start = Instant::now(); + lvgl::task_handler(); + sleep(Duration::from_millis(5)); + lvgl::tick_inc(Instant::now().duration_since(Start)); + } +} diff --git a/Modules/Graphics/src/Display.rs b/Modules/Graphics/src/Display.rs index a41a686..f2ab7d5 100644 --- a/Modules/Graphics/src/Display.rs +++ b/Modules/Graphics/src/Display.rs @@ -1,68 +1,60 @@ -use Screen::Prelude::{Area_type, Color_type, Point_type, Refresh_area_type, Screen_traits}; +use std::mem::transmute; -use crate::Draw_buffer_type; +use Screen::Prelude::{Area_type, Color_type, Point_type, Screen_traits}; -pub struct Display_type(lvgl::Display); +use crate::{Draw_buffer::Draw_buffer_type, Result_type}; -impl Display_type { - pub fn New, const Buffer_size: usize>( - Screen: &mut Screen_type, - Draw_buffer: Draw_buffer_type, - ) -> Result { - let Resolution = match Screen.Get_resolution() { - Ok(Resolution) => Resolution, - Err(_) => return Err(()), - }; +pub struct Display_type { + Display: lvgl::Display, + #[allow(dead_code)] + Screen: Box, +} + +unsafe impl Send for Display_type {} + +unsafe impl Sync for Display_type {} +impl Display_type { + pub fn New( + mut Screen: Box, + Resolution: Point_type, + ) -> Result_type { let Binding_function = |Refresh: &lvgl::DisplayRefresh| { let Area = Area_type::New( Point_type::New(Refresh.area.x1, Refresh.area.y1), - Point_type::New( - Refresh.area.x2 - Refresh.area.x1, - Refresh.area.y2 - Refresh.area.y1, - ), + Point_type::New(Refresh.area.x2, Refresh.area.y2), ); - let mut Buffer = [Color_type { - Red: 0, - Green: 0, - Blue: 0, - }; Buffer_size]; - - for (Destination, Source) in Buffer.iter_mut().zip(Refresh.colors.iter()) { - *Destination = Color_type { - Red: Source.r() << 3, - Green: Source.g() << 2, - Blue: Source.b() << 3, - }; - } - - let Refresh_area = Refresh_area_type:: { Area, Buffer }; + let Buffer: &[Color_type; Buffer_size] = unsafe { + transmute( + // Avoid copying the buffer, but the colors must be in the same format + &Refresh.colors, + ) + }; - Screen.Update(&Refresh_area); + let _ = Screen.Update(Area, Buffer); }; - let LVGL_display = match lvgl::Display::register( + let Draw_buffer = Draw_buffer_type::::default(); + + let LVGL_display = lvgl::Display::register( Draw_buffer.into(), - Resolution.X as u32, - Resolution.Y as u32, + Resolution.Get_x() as u32, + Resolution.Get_y() as u32, Binding_function, - ) { - Ok(Display) => Display, - Err(_) => return Err(()), - }; + )?; - Ok(Display_type(LVGL_display)) + Ok(Self { + Display: LVGL_display, + Screen, + }) } pub fn Get_lvgl_display(&self) -> &lvgl::Display { - &self.0 + &self.Display } - pub fn Get_object(&self) -> Result { - match self.0.get_scr_act() { - Ok(Object) => Ok(Object), - Err(_) => Err(()), - } + pub fn Get_object(&self) -> Result_type { + Ok(self.Display.get_scr_act()?) } } diff --git a/Modules/Graphics/src/Draw_buffer.rs b/Modules/Graphics/src/Draw_buffer.rs new file mode 100644 index 0000000..cd702a8 --- /dev/null +++ b/Modules/Graphics/src/Draw_buffer.rs @@ -0,0 +1,16 @@ +#[repr(transparent)] +pub struct Draw_buffer_type(lvgl::DrawBuffer); + +impl Default for Draw_buffer_type { + fn default() -> Self { + Draw_buffer_type(lvgl::DrawBuffer::::default()) + } +} + +impl From> + for lvgl::DrawBuffer +{ + fn from(Draw_buffer: Draw_buffer_type) -> Self { + Draw_buffer.0 + } +} diff --git a/Modules/Graphics/src/Error.rs b/Modules/Graphics/src/Error.rs new file mode 100644 index 0000000..b875b86 --- /dev/null +++ b/Modules/Graphics/src/Error.rs @@ -0,0 +1,46 @@ +use std::sync::PoisonError; + +use lvgl::{DisplayError, LvError}; + +pub type Result_type = Result; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(C)] +pub enum Error_type { + Invalid_reference, + Already_initialized, + Not_initialized, + Out_of_memory, + Already_in_use, + Poisoned_lock, + Failed_to_register, + Not_registered, + Not_available, +} + +impl From for Error_type { + fn from(Error: DisplayError) -> Self { + match Error { + DisplayError::NotAvailable => Error_type::Not_available, + DisplayError::FailedToRegister => Error_type::Failed_to_register, + DisplayError::NotRegistered => Error_type::Not_registered, + } + } +} + +impl From for Error_type { + fn from(Error: LvError) -> Self { + match Error { + LvError::InvalidReference => Error_type::Invalid_reference, + LvError::Uninitialized => Error_type::Not_initialized, + LvError::LvOOMemory => Error_type::Out_of_memory, + LvError::AlreadyInUse => Error_type::Already_in_use, + } + } +} + +impl From> for Error_type { + fn from(_: PoisonError) -> Self { + Error_type::Poisoned_lock + } +} diff --git a/Modules/Graphics/src/Input.rs b/Modules/Graphics/src/Input.rs index 6df0f80..730037c 100644 --- a/Modules/Graphics/src/Input.rs +++ b/Modules/Graphics/src/Input.rs @@ -1,93 +1,52 @@ use lvgl::input_device::{pointer, InputDriver}; -use Screen::Prelude::{Input_traits, Touch_type}; +use File_system::Prelude::File_type; +use Screen::Prelude::Touch_type; -use crate::Display::Display_type; +use crate::{Display::Display_type, Result_type}; -pub struct Input_type(pointer::Pointer); - -impl Input_type { - pub fn New( - Pointer: &Pointer_type, - Display: &Display_type, - ) -> Result { - let Binding_function = || { - let (Position, Touch) = Pointer.Get_latest_input(); - let Input_data = - pointer::PointerInputData::Touch((Position.X as i32, Position.Y as i32).into()); - - let Input_data = match Touch { - Touch_type::Pressed => Input_data.pressed(), - Touch_type::Released => Input_data.released(), - }; - - Input_data.once() - }; - - match pointer::Pointer::register(Binding_function, Display.Get_lvgl_display()) { - Ok(Input) => Ok(Input_type(Input)), - Err(_) => Err(()), - } - } +pub struct Input_type { + #[allow(dead_code)] + Pointer: pointer::Pointer, } -#[cfg(test)] -mod tests { - use crate::Draw_buffer_type; - - use super::*; - use lvgl::Widget; - use std::{ - thread::sleep, - time::{Duration, Instant}, - }; - use Screen::{Drivers::SDL2::New_touchscreen, Prelude::Point_type}; +unsafe impl Send for Input_type {} - #[test] - #[ignore] - fn Test_SDL2() { - const Horizontal_resolution: u32 = 800; - const Vertical_resolution: u32 = 480; - const Buffer_size: usize = (Horizontal_resolution * Vertical_resolution / 2) as usize; +unsafe impl Sync for Input_type {} - let Touchscreen = New_touchscreen(Point_type::New( - Horizontal_resolution as i16, - Vertical_resolution as i16, - )); - assert!(Touchscreen.is_ok()); - let (mut Screen, mut Pointer) = Touchscreen.unwrap(); +impl Input_type { + pub fn New(File: File_type, Display: &Display_type) -> Result_type { + let Binding_closure = move || { + let mut Buffer = [0u8; 5]; - let Buffer = Draw_buffer_type::::default(); + let Size = File + .Read(&mut Buffer) + .expect("Error reading from input device"); - let Display = Display_type::New(&mut Screen, Buffer); - assert!(Display.is_ok()); - let Display = Display.unwrap(); + if Size != Buffer.len() { + panic!("Invalid input data received from input device"); + } - let _Input = Input_type::New(&Pointer, &Display); - assert!(_Input.is_ok()); - let mut _Input = _Input.unwrap(); + let X = u16::from_le_bytes([Buffer[0], Buffer[1]]); + let Y = u16::from_le_bytes([Buffer[2], Buffer[3]]); - let Display_object = Display.Get_object(); - assert!(Display_object.is_ok()); - let mut Display_object = Display_object.unwrap(); + let Touch = Touch_type::try_from(Buffer[4]) + .expect("Invalid touch type received from input device"); - let _ = lvgl::widgets::Slider::create(&mut Display_object); + let Input_data = pointer::PointerInputData::Touch((X as i32, Y as i32).into()); - let Calendar = lvgl::widgets::Calendar::create(&mut Display_object); - assert!(Calendar.is_ok()); - let mut Calendar = Calendar.unwrap(); + let Input_data = match Touch { + Touch_type::Pressed => Input_data.pressed(), + Touch_type::Released => Input_data.released(), + }; - let mut Style = lvgl::style::Style::default(); - Style.set_bg_color(lvgl::Color::from_rgb((255, 0, 0))); + Input_data.once() + }; - let _ = Calendar.add_style(lvgl::obj::Part::Any, &mut Style); - let _ = Calendar.set_align(lvgl::Align::Center, 0, 0); + Binding_closure(); - loop { - let Start = Instant::now(); - lvgl::task_handler(); - sleep(Duration::from_millis(5)); - lvgl::tick_inc(Instant::now().duration_since(Start)); - Pointer.Update(); - } + Ok(Self { + Pointer: pointer::Pointer::register(Binding_closure, Display.Get_lvgl_display())?, + // File: File, + }) } } diff --git a/Modules/Graphics/src/Manager.rs b/Modules/Graphics/src/Manager.rs new file mode 100644 index 0000000..6e0155d --- /dev/null +++ b/Modules/Graphics/src/Manager.rs @@ -0,0 +1,53 @@ +use std::sync::Mutex; + +use File_system::Prelude::File_type; +use Screen::Prelude::{Point_type, Screen_traits}; + +use crate::{Display_type, Error_type, Input_type, Result_type}; + +/// Avoid using Arc, because the manager is a singleton. +static mut Manager_instance: Option = None; + +pub fn Initialize() -> Result_type<&'static Manager_type> { + unsafe { + if Is_initialized() { + return Err(Error_type::Already_initialized); + } + + Manager_instance.replace(Manager_type::New()); + } + Get_instance() +} + +pub fn Is_initialized() -> bool { + unsafe { Manager_instance.is_some() } +} + +pub fn Get_instance() -> Result_type<&'static Manager_type> { + unsafe { Manager_instance.as_ref().ok_or(Error_type::Not_initialized) } +} + +struct Inner(Option); + +pub struct Manager_type(Mutex); + +impl Manager_type { + fn New() -> Self { + Self(Mutex::new(Inner(None))) + } + + pub fn Create_display( + &self, + Screen: Box, + Resolution: Point_type, + Input_path: File_type, + ) -> Result_type { + let Display = Display_type::New::(Screen, Resolution)?; + + let Input = Input_type::New(Input_path, &Display)?; + + self.0.lock()?.0.replace(Input); + + Ok(Display) + } +} diff --git a/Modules/Graphics/src/lib.rs b/Modules/Graphics/src/lib.rs index e0d1c7c..04c5114 100644 --- a/Modules/Graphics/src/lib.rs +++ b/Modules/Graphics/src/lib.rs @@ -3,29 +3,18 @@ #![allow(non_upper_case_globals)] mod Display; +mod Draw_buffer; +mod Error; mod Input; +mod Manager; //mod Window; pub use Display::*; +pub use Draw_buffer::*; +pub use Error::*; pub use Input::*; +pub use Manager::*; //pub use Window::*; pub use lvgl; pub use lvgl::sys; - -#[repr(transparent)] -pub struct Draw_buffer_type(lvgl::DrawBuffer); - -impl Default for Draw_buffer_type { - fn default() -> Self { - Draw_buffer_type(lvgl::DrawBuffer::::default()) - } -} - -impl From> - for lvgl::DrawBuffer -{ - fn from(Draw_buffer: Draw_buffer_type) -> Self { - Draw_buffer.0 - } -} From 03f48bc9d7eab016711f406c4595c0dcf66baa58 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:48:32 -0400 Subject: [PATCH 36/39] Add opt-level = 0 as comment into main Cargo.toml --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 72c9395..ff03477 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ opt-level = "s" # Optimize binary size [profile.dev] debug = true # Symbols are nice and they don't increase the size on Flash. opt-level = "z" # Optimize binary size and turn off loop vectorization. +# opt-level = 0 # Disable optimizations to speed up compilation and in case of bugs. [features] ESP32 = ["Xtensa"] From e88b6dc804392931e6f9b445edb0c8f8c3615705 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:54:24 -0400 Subject: [PATCH 37/39] Update file system bindings and its unit test --- Modules/Bindings/Tests/File_system.rs | 15 +++----- Modules/Bindings/src/File_system.rs | 55 ++++++++++++--------------- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/Modules/Bindings/Tests/File_system.rs b/Modules/Bindings/Tests/File_system.rs index 0d10ff3..5830d4a 100644 --- a/Modules/Bindings/Tests/File_system.rs +++ b/Modules/Bindings/Tests/File_system.rs @@ -3,10 +3,7 @@ #![allow(non_upper_case_globals)] use Bindings::File_system_bindings; -use File_system::{ - Drivers::Native::File_system_type, - Prelude::{Path_type, Virtual_file_system_type}, -}; +use File_system::{Drivers::Native::File_system_type, Prelude::Path_type}; use Virtual_machine::{Data_type, Instantiate_test_environment, WasmValue}; #[test] @@ -16,17 +13,15 @@ fn Integration_test() { ); let Virtual_file_system = - Virtual_file_system_type::New(Task::Manager_type::New(), Users::Manager_type::New()); + File_system::Initialize(Task::Manager_type::New(), Users::Manager_type::New()) + .expect("Failed to initialize file system"); let Native_file_system = File_system_type::New().expect("Failed to create file system"); let _ = Virtual_file_system.Mount(Box::new(Native_file_system), Path_type::Get_root()); - let (_Runtime, _Module, Instance) = Instantiate_test_environment( - Binary_buffer, - File_system_bindings::New(Virtual_file_system.clone()), - &Data_type::New(), - ); + let (_Runtime, _Module, Instance) = + Instantiate_test_environment(Binary_buffer, File_system_bindings, &Data_type::New()); assert_eq!( Instance diff --git a/Modules/Bindings/src/File_system.rs b/Modules/Bindings/src/File_system.rs index 0918385..8160200 100644 --- a/Modules/Bindings/src/File_system.rs +++ b/Modules/Bindings/src/File_system.rs @@ -1,28 +1,19 @@ -use std::mem::MaybeUninit; - use Binding_tool::Bind_function_native; use File_system::Prelude::*; use Virtual_machine::{Function_descriptor_type, Function_descriptors, Registrable_trait}; -pub struct File_system_bindings {} -impl Registrable_trait for File_system_bindings { - fn Get_functions(&self) -> &[Function_descriptor_type] { - &File_system_bindings_functions - } -} +pub struct File_system_bindings; impl File_system_bindings { - pub fn New(File_system: Virtual_file_system_type) -> Self { - unsafe { - Virtual_file_system.write(File_system); - } - + pub fn New() -> Self { Self {} } } -fn Get_virtual_file_system() -> &'static Virtual_file_system_type { - unsafe { Virtual_file_system.assume_init_ref() } +impl Registrable_trait for File_system_bindings { + fn Get_functions(&self) -> &[Function_descriptor_type] { + &File_system_bindings_functions + } } const File_system_bindings_functions: [Function_descriptor_type; 8] = Function_descriptors!( @@ -36,18 +27,20 @@ const File_system_bindings_functions: [Function_descriptor_type; 8] = Function_d Delete_binding ); -static mut Virtual_file_system: MaybeUninit = MaybeUninit::uninit(); - -fn New_path(Path: &str) -> Result<&Path_type> { +fn New_path(Path: &str) -> Result_type<&Path_type> { Path_type::New(Path).ok_or(Error_type::Invalid_path) } +fn Get_virtual_file_system() -> &'static Virtual_file_system_type { + File_system::Get_instance().expect("File system not initialized") +} + #[Bind_function_native(Prefix = "File_system")] fn Open( Path: &str, Flags: Flags_type, File_identifier: &mut Unique_file_identifier_type, -) -> Result<()> { +) -> Result_type<()> { let Path = New_path(Path)?; *File_identifier = Get_virtual_file_system().Open(Path, Flags)?; @@ -56,7 +49,7 @@ fn Open( } #[Bind_function_native(Prefix = "File_system")] -fn Close_file(File_identifier: Unique_file_identifier_type) -> Result<()> { +fn Close_file(File_identifier: Unique_file_identifier_type) -> Result_type<()> { Get_virtual_file_system().Close(File_identifier) } @@ -65,7 +58,7 @@ fn Read( File_identifier: Unique_file_identifier_type, Buffer: &mut [u8], Read_size: &mut Size_type, -) -> Result<()> { +) -> Result_type<()> { *Read_size = Get_virtual_file_system().Read(File_identifier, Buffer)?; Ok(()) @@ -76,19 +69,19 @@ fn Write( File_identifier: Unique_file_identifier_type, Buffer: &[u8], Write_size: &mut Size_type, -) -> Result<()> { +) -> Result_type<()> { *Write_size = Get_virtual_file_system().Write(File_identifier, Buffer)?; Ok(()) } #[Bind_function_native(Prefix = "File_system")] -fn Flush(File_identifier: Unique_file_identifier_type) -> Result<()> { +fn Flush(File_identifier: Unique_file_identifier_type) -> Result_type<()> { Get_virtual_file_system().Flush(File_identifier) } #[Bind_function_native(Prefix = "File_system")] -fn Get_file_type(Path: &str, Type: &mut u32) -> Result<()> { +fn Get_file_type(Path: &str, Type: &mut u32) -> Result_type<()> { let Path = New_path(Path)?; *Type = Get_virtual_file_system().Get_type(Path)? as u32; @@ -97,7 +90,7 @@ fn Get_file_type(Path: &str, Type: &mut u32) -> Result<()> { } #[Bind_function_native(Prefix = "File_system")] -fn Get_file_size(Path: &str, Size: &mut Size_type) -> Result<()> { +fn Get_file_size(Path: &str, Size: &mut Size_type) -> Result_type<()> { let Path = New_path(Path)?; *Size = Get_virtual_file_system().Get_size(Path)?; @@ -110,14 +103,14 @@ fn Set_position( File_identifier: Unique_file_identifier_type, Position: &Position_type, Result_value: &mut Size_type, -) -> Result<()> { +) -> Result_type<()> { *Result_value = Get_virtual_file_system().Set_position(File_identifier, Position)?; Ok(()) } #[Bind_function_native(Prefix = "File_system")] -fn Delete_file(Path: &str, Recursive: bool) -> Result<()> { +fn Delete_file(Path: &str, Recursive: bool) -> Result_type<()> { let Path = New_path(Path)?; Get_virtual_file_system().Delete(Path, Recursive)?; @@ -126,7 +119,7 @@ fn Delete_file(Path: &str, Recursive: bool) -> Result<()> { } #[Bind_function_native(Prefix = "File_system")] -fn Create_file(Path: &str) -> Result<()> { +fn Create_file(Path: &str) -> Result_type<()> { let Path = New_path(Path)?; Get_virtual_file_system() @@ -137,7 +130,7 @@ fn Create_file(Path: &str) -> Result<()> { } #[Bind_function_native(Prefix = "File_system")] -fn Create_directory(Path: &str, Recursive: bool) -> Result<()> { +fn Create_directory(Path: &str, Recursive: bool) -> Result_type<()> { let Path = New_path(Path)?; Get_virtual_file_system().Create_directory(Path, Recursive)?; @@ -146,7 +139,7 @@ fn Create_directory(Path: &str, Recursive: bool) -> Result<()> { } #[Bind_function_native(Prefix = "File_system")] -fn Delete(Path: &str, Recursive: bool) -> Result<()> { +fn Delete(Path: &str, Recursive: bool) -> Result_type<()> { let Path = New_path(Path)?; Get_virtual_file_system().Delete(Path, Recursive)?; @@ -155,7 +148,7 @@ fn Delete(Path: &str, Recursive: bool) -> Result<()> { } #[Bind_function_native(Prefix = "File_system")] -fn Exists(Path: &str, Exists: &mut bool) -> Result<()> { +fn Exists(Path: &str, Exists: &mut bool) -> Result_type<()> { let Path = New_path(Path)?; *Exists = Get_virtual_file_system().Exists(Path)?; From 23f566b572b6c18d139bfc34c622e7ce3e5d4d54 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:54:43 -0400 Subject: [PATCH 38/39] Fix task bindings unit test warnings --- Modules/Bindings/Tests/Task.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Modules/Bindings/Tests/Task.rs b/Modules/Bindings/Tests/Task.rs index 606ddcc..400785b 100644 --- a/Modules/Bindings/Tests/Task.rs +++ b/Modules/Bindings/Tests/Task.rs @@ -2,11 +2,7 @@ #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] -use Bindings::{File_system_bindings, Task_bindings}; -use File_system::{ - Drivers::Native::File_system_type, - Prelude::{Path_type, Virtual_file_system_type}, -}; +use Bindings::Task_bindings; use Virtual_machine::{Data_type, Instantiate_test_environment, WasmValue}; #[test] From 0d95d499448ce6abb8e92f46a715e4d3804f7151 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Sat, 6 Jul 2024 00:55:06 -0400 Subject: [PATCH 39/39] Disable graphics bindings and its integration test --- Modules/Bindings/Cargo.toml | 6 +++--- Modules/Bindings/src/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/Bindings/Cargo.toml b/Modules/Bindings/Cargo.toml index de07b61..5a8907d 100644 --- a/Modules/Bindings/Cargo.toml +++ b/Modules/Bindings/Cargo.toml @@ -22,7 +22,7 @@ path = "Tests/File_system.rs" name = "Task_bindings_tests" path = "Tests/Task.rs" -[[test]] -name = "Graphics_bindings_tests" -path = "Tests/Graphics.rs" +# [[test]] +# name = "Graphics_bindings_tests" +# path = "Tests/Graphics.rs" diff --git a/Modules/Bindings/src/lib.rs b/Modules/Bindings/src/lib.rs index 45f84f6..3884884 100644 --- a/Modules/Bindings/src/lib.rs +++ b/Modules/Bindings/src/lib.rs @@ -8,5 +8,5 @@ pub use File_system::*; mod Task; pub use Task::*; -mod Graphics; -pub use Graphics::*; +//mod Graphics; +//pub use Graphics::*;