Open a file or directory This will create files but not directories
(mut dir: Arc<RwLock<dyn DirLike + Sync + Send>>, path: &Path, flags: u64)
| 62 | /// |
| 63 | /// This will create files but not directories |
| 64 | fn open(mut dir: Arc<RwLock<dyn DirLike + Sync + Send>>, path: &Path, flags: u64) -> Result<CommHandle, syscalls::SyscallError> { |
| 65 | println!("[std:open] Opening {:?}", path); |
| 66 | |
| 67 | let mut path_iter = path.iter().peekable(); |
| 68 | while let Some(component) = path_iter.next() { |
| 69 | // Convert to a string for indexing |
| 70 | let key = component.to_str().unwrap(); |
| 71 | |
| 72 | let result_subdir = dir.read().get_dir(key); |
| 73 | if let Ok(subdir) = result_subdir { |
| 74 | if path_iter.peek().is_none() { |
| 75 | // No further path components => Opening an existing directory |
| 76 | let readwrite = (flags & message::O_WRITE) == message::O_WRITE; |
| 77 | println!("Starting handle_directory({}, rw:{})", key, readwrite); |
| 78 | |
| 79 | // Make a new communication handle pair |
| 80 | let (handle, client_handle) = syscalls::new_rendezvous()?; |
| 81 | |
| 82 | // Start a thread |
| 83 | thread::spawn(move || { |
| 84 | handle_directory(subdir, handle, readwrite, |message| { |
| 85 | println!("[std:handle subdir] Unexpected message {:?}", message); |
| 86 | }); |
| 87 | })?; // Might fail to start a thread |
| 88 | |
| 89 | // Return the other handle to the client |
| 90 | return Ok(client_handle) |
| 91 | } else { |
| 92 | // Further components => Move to subdirectory |
| 93 | dir = subdir; |
| 94 | } |
| 95 | } else { |
| 96 | let result_file = dir.read().get_file(key); |
| 97 | if let Ok(file) = result_file { |
| 98 | if path_iter.peek().is_some() { |
| 99 | println!("Error opening path {:?}: {} is a file not a directory", path, key); |
| 100 | return Err(syscalls::SYSCALL_ERROR_NOT_DIR); |
| 101 | } |
| 102 | // No more components -> Opening an existing file |
| 103 | |
| 104 | if (flags & message::O_TRUNCATE) == message::O_TRUNCATE { |
| 105 | // Delete contents |
| 106 | file.write().clear()?; |
| 107 | } |
| 108 | |
| 109 | // Make a new communication handle pair |
| 110 | let (handle, client_handle) = syscalls::new_rendezvous()?; |
| 111 | |
| 112 | // Start a thread |
| 113 | if (flags & message::O_WRITE) == message::O_WRITE { |
| 114 | thread::spawn(move || { |
| 115 | handle_file_readwrite(file, handle); |
| 116 | })?; // Might fail to start thread |
| 117 | } else { |
| 118 | thread::spawn(move || { |
| 119 | handle_file_readonly(file, handle); |
| 120 | })?; |
| 121 | } |
no test coverage detected