Move checks into error handling of std::fs::rename (where possible)

This commit is contained in:
Jakub Konka
2019-08-11 22:00:58 +02:00
parent 1b7d9bed2b
commit b14570e887

View File

@@ -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() { if old_path.is_dir() && new_path.is_file() {
return Err(host::__WASI_ENOTDIR); return Err(host::__WASI_ENOTDIR);
} }
if old_path.is_file() && new_path.is_dir() {
return Err(host::__WASI_EISDIR);
}
// TODO handle symlinks // TODO handle symlinks
fs::rename(&old_path, &new_path).or_else(|e| match e.raw_os_error() { fs::rename(&old_path, &new_path).or_else(|e| match e.raw_os_error() {
Some(e) => { Some(e) => {
if old_path.is_dir() && new_path.is_dir() { use winx::winerror::WinError;
if !dir_is_empty(&new_path).map_err(errno_from_ioerror)? {
Err(host::__WASI_ENOTEMPTY) 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 { } 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) fs::remove_dir(&new_path)
.and_then(|()| fs::rename(old_path, new_path)) .and_then(|()| fs::rename(old_path, new_path))
.map_err(errno_from_ioerror) .map_err(errno_from_ioerror)
} }
} else { }
log::debug!("path_rename at rename error={:?}", e); e => Err(host_impl::errno_from_win(e)),
Err(errno_from_host(e))
} }
} }
None => { 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> { pub(crate) fn num_hardlinks(file: &File, _metadata: &Metadata) -> io::Result<u64> {
Ok(winx::file::get_fileinfo(file)?.nNumberOfLinks.into()) Ok(winx::file::get_fileinfo(file)?.nNumberOfLinks.into())
} }