mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(fs): support rename across filesystems
Rather than expect the user to know that they need to handle a special case when renaming across filesystems, we can just handle it for them. Fixes #3092
This commit is contained in:
parent
5919f31891
commit
9e40cbe495
1 changed files with 25 additions and 4 deletions
|
@ -179,16 +179,14 @@ impl FileSystem for RealFs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rename_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> {
|
fn rename_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> {
|
||||||
fs::rename(oldpath, newpath).map_err(Into::into)
|
rename(oldpath, newpath)
|
||||||
}
|
}
|
||||||
async fn rename_async(
|
async fn rename_async(
|
||||||
&self,
|
&self,
|
||||||
oldpath: PathBuf,
|
oldpath: PathBuf,
|
||||||
newpath: PathBuf,
|
newpath: PathBuf,
|
||||||
) -> FsResult<()> {
|
) -> FsResult<()> {
|
||||||
spawn_blocking(move || fs::rename(oldpath, newpath))
|
spawn_blocking(move || rename(&oldpath, &newpath)).await?
|
||||||
.await?
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> {
|
fn link_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> {
|
||||||
|
@ -598,6 +596,29 @@ fn read_dir(path: &Path) -> FsResult<Vec<FsDirEntry>> {
|
||||||
Ok(entries)
|
Ok(entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rename(oldpath: &Path, newpath: &Path) -> FsResult<()> {
|
||||||
|
match fs::rename(oldpath, newpath) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(err) => {
|
||||||
|
if err.raw_os_error() == Some(libc::EXDEV) {
|
||||||
|
// EXDEV: rename fails because oldpath and newpath are not on the same
|
||||||
|
// mounted filesystem. We need to do a copy and remove.
|
||||||
|
//
|
||||||
|
// This check can be replaced with the following once
|
||||||
|
// https://github.com/rust-lang/rust/issues/86442 stabilizes:
|
||||||
|
//
|
||||||
|
// if err.kind() == io::ErrorKind::CrossDeviceLink
|
||||||
|
//
|
||||||
|
copy_file(oldpath, newpath)?;
|
||||||
|
fs::remove_file(oldpath)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(err.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fn symlink(
|
fn symlink(
|
||||||
oldpath: &Path,
|
oldpath: &Path,
|
||||||
|
|
Loading…
Reference in a new issue