Move checks into error handling of std::fs::rename (where possible)
This commit is contained in:
@@ -213,26 +213,29 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
|
||||
if old_path.is_dir() && new_path.is_file() {
|
||||
return Err(host::__WASI_ENOTDIR);
|
||||
}
|
||||
if old_path.is_file() && new_path.is_dir() {
|
||||
return Err(host::__WASI_EISDIR);
|
||||
}
|
||||
|
||||
// TODO handle symlinks
|
||||
|
||||
fs::rename(&old_path, &new_path).or_else(|e| match e.raw_os_error() {
|
||||
Some(e) => {
|
||||
if old_path.is_dir() && new_path.is_dir() {
|
||||
if !dir_is_empty(&new_path).map_err(errno_from_ioerror)? {
|
||||
Err(host::__WASI_ENOTEMPTY)
|
||||
use winx::winerror::WinError;
|
||||
|
||||
log::debug!("path_rename at rename error code={:?}", e);
|
||||
match WinError::from_u32(e as u32) {
|
||||
WinError::ERROR_ACCESS_DENIED => {
|
||||
// So most likely dealing with new_path == dir.
|
||||
// Eliminate case old_path == file first.
|
||||
if old_path.is_file() {
|
||||
Err(host::__WASI_EISDIR)
|
||||
} else {
|
||||
// remove new_path dir and rename
|
||||
// Ok, let's try removing an empty dir at new_path if it exists
|
||||
// and is a nonempty dir.
|
||||
fs::remove_dir(&new_path)
|
||||
.and_then(|()| fs::rename(old_path, new_path))
|
||||
.map_err(errno_from_ioerror)
|
||||
}
|
||||
} else {
|
||||
log::debug!("path_rename at rename error={:?}", e);
|
||||
Err(errno_from_host(e))
|
||||
}
|
||||
e => Err(host_impl::errno_from_win(e)),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@@ -242,14 +245,6 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
|
||||
})
|
||||
}
|
||||
|
||||
fn dir_is_empty<P: AsRef<Path>>(path: P) -> io::Result<bool> {
|
||||
let mut it = std::fs::read_dir(path)?;
|
||||
match it.next() {
|
||||
Some(_) => Ok(false),
|
||||
None => Ok(true),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn num_hardlinks(file: &File, _metadata: &Metadata) -> io::Result<u64> {
|
||||
Ok(winx::file::get_fileinfo(file)?.nNumberOfLinks.into())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user