diff --git a/backend/src/utils/file/file_lock_manager.rs b/backend/src/utils/file/file_lock_manager.rs index f604641f5..30e23d567 100644 --- a/backend/src/utils/file/file_lock_manager.rs +++ b/backend/src/utils/file/file_lock_manager.rs @@ -1,10 +1,12 @@ use std::collections::HashMap; +use std::env; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::{fmt, io}; use tokio::sync::{Mutex, RwLock}; use tokio::sync::{OwnedRwLockReadGuard, OwnedRwLockWriteGuard}; use shared::error::str_to_io_error; +use path_clean::PathClean; #[derive(Clone)] pub struct FileLockManager { @@ -44,14 +46,15 @@ impl FileLockManager { // Helper function: retrieves or creates a lock for a file. async fn get_or_create_lock(&self, path: &Path) -> Arc> { + let normalized_path = normalize_path(path); let mut locks = self.locks.lock().await; - if let Some(lock) = locks.get(path) { + if let Some(lock) = locks.get(&normalized_path) { return lock.clone(); } let file_lock = Arc::new(RwLock::new(())); - locks.insert(path.to_path_buf(), file_lock.clone()); + locks.insert(normalized_path, file_lock.clone()); drop(locks); file_lock } @@ -94,3 +97,17 @@ impl FileWriteGuard { Self { _guard: guard } } } + +fn normalize_path(path: &Path) -> PathBuf { + if let Ok(canonical) = path.canonicalize() { + return canonical; + } + + let base = if path.is_absolute() { + path.to_path_buf() + } else { + env::current_dir().unwrap_or_else(|_| PathBuf::from("./")).join(path) + }; + + base.clean() +}