filesys.rs : decompname & find_dir

This commit is contained in:
Baptiste 2023-03-29 18:04:55 +02:00
parent 79bfcf6b57
commit f4420d9306
3 changed files with 121 additions and 15 deletions

View File

@ -1,6 +1,103 @@
use super::directory;
pub const DIRECTORY_SECTOR: i32 = 1;
/// decompose the name of the first directory
/// of the path given in argument, as well as the remainder of the path.
/// if we call decompname("/bin/new/halt", head, tail), we get "bin" in head and "/new/halt" in tail
/// returns true if everything goes ok, otherwise, return false.
/// head and tail MUST be large enough to contain the resulting strings
///
/// ### parameters
///
/// - **orig_path** the pathname we want to decompose
/// - **head** the first element in the path (for instance "bin")
/// - **tail** the remainder of the string (for instance "/new/halt")
pub fn decomp_name(origin_path: String, head: &mut String, tail: &mut String) -> bool {
let mut working_path = origin_path;
// remove the leading "/" if any
if working_path.get(0..1).unwrap_or_else(|| "").eq("/") {
working_path = (&working_path[1..]).to_string();
}
if working_path.contains("/") {
let index = working_path.find("/").expect("shouldn't happen");
*head = working_path[..index].to_string();
*tail = working_path[index..].to_string();
return true;
} else {
*head = "".to_string();
*tail = origin_path;
return false;
}
}
/// this function takes a complete pathname and returns
/// the disc sector of the fileheader of the directory.
/// return -1 in case of error
///
/// IMPORTANT WARNING : name is modified : after the execution, name
/// contains only the name of the file
/// (e.g. if we called find_dir("/bin/halt") then name is "halt" after the execution,
/// the function returns the sector number of the directory "/bin").
///
/// Actually, this function does not support complete pathnames
/// This is one of the objectives of the file system assignment
///
/// ### parameters
///
/// - **name** is the complete name (relatively to the root directory).
/// its content will be modified!
pub fn find_dir(name: &mut String) -> i32 {
let directory = directory::init_directory(config.num_dir_entries);
directory.fetch_from(filesys::get_dir_file());
let mut sector = DIRECTORY_SECTOR;
let mut dirname = String::from("");
let mut reminder = String::from("");
while decomp_name(name.to_string(), &mut dirname, &mut reminder) {
*name = reminder;
// Get the sector of the file/directory corresponding to 'name'
sector = directory.find(dirname);
if sector < 0 {
return -1; // This file/directory does not exist
}
let file = openfile::init_open_file(sector);
if file.get_file_header().is_dir() {
directory.fetch_from(&file);
} else {
return -1;
}
}
*name = reminder;
sector
}
pub struct Filesys { pub struct Filesys {
pub free_map_file : Open_File, //Bit map of free disk blocks, represented as a file pub free_map_file: Open_file, //Bit map of free disk blocks, represented as a file
pub directory_file : Open_file //"Root" directory -- list of file names, represented as a file pub directory_file: Open_file, //"Root" directory -- list of file names, represented as a file
} }
impl Filesys {
/// Initialize the file system.
/// If format = true, the disk has nothing on it,
/// and we need to initialize the disk to contain an empty directory,
/// and a bitmap of free sectors (with almost but not all of the sectors marked as free).
///
/// If format = false, we just have to open the files
/// representing the bitmap and the directory.
///
/// ### parameters
///
/// - **format** should we initialize the disk?
pub fn init_filesys(format: bool) -> Filesys {
if format {
let free_map = bitmap::init_bitmap();
}
}
}

View File

@ -1,19 +1,23 @@
use std::{fs::File, io::{Seek, SeekFrom, Read}}; use std::{
fs::File,
io::{Read, Seek, SeekFrom},
};
use super::filesys; use super::filesys;
pub const TRANSFER_SIZE: usize = 10; pub const TRANSFER_SIZE: usize = 10;
/// copy the contents of the UNIX file "from" to the Nachos file "to" /// copy the contents of the UNIX file "from" to the Nachos file "to"
/// ///
/// `panic!` when the file from doesn't exist /// `panic!` when the file from doesn't exist
/// ///
/// ### parameters
///
/// - **from** file UNIX /// - **from** file UNIX
/// - **to** BurritOS file /// - **to** BurritOS file
pub fn copy(from : &str, to : &str) { pub fn copy(from: &str, to: &str) {
let file_from_opt = File::options().read(true).open(from); let file_from_opt = File::options().read(true).open(from);
let mut file_from : File; let mut file_from: File;
match file_from_opt { match file_from_opt {
Err(e) => { Err(e) => {
panic!("Copy: couldn't open Unix file {}", from); panic!("Copy: couldn't open Unix file {}", from);
@ -35,7 +39,9 @@ pub fn copy(from : &str, to : &str) {
let mut buffer = [0; TRANSFER_SIZE]; let mut buffer = [0; TRANSFER_SIZE];
loop { loop {
let amount_read = file_from.read(&mut buffer).expect("copy : couldn't read the UNIX file"); let amount_read = file_from
.read(&mut buffer)
.expect("copy : couldn't read the UNIX file");
open_file.write(&buffer[..amount_read]); open_file.write(&buffer[..amount_read]);
if amount_read != TRANSFER_SIZE { if amount_read != TRANSFER_SIZE {
@ -45,11 +51,13 @@ pub fn copy(from : &str, to : &str) {
} }
/// Print the contents of the Nachos file "name". /// Print the contents of the Nachos file "name".
/// ///
/// `panic!` when the file name doewn't exist /// `panic!` when the file name doewn't exist
/// ///
/// ### parameters
///
/// - **name** of the BurritOS file /// - **name** of the BurritOS file
pub fn print(name : &str) { pub fn print(name: &str) {
let open_file = filesys::open(name); let open_file = filesys::open(name);
let mut buffer = [0; TRANSFER_SIZE]; let mut buffer = [0; TRANSFER_SIZE];
@ -63,4 +71,4 @@ pub fn print(name : &str) {
break; break;
} }
} }
} }

View File

@ -1,2 +1,3 @@
pub mod directory;
pub mod filesys;
pub mod fsmisc; pub mod fsmisc;
pub mod filesys;