Fix path_rename on *nix hosts

The fix contains an errno remapping in macOS case where in case
when we try to rename a file into a path with a trailing slash an
ENOENT is returned. In this case, if the destination does not exist,
an ENOTDIR should be thrown as is thrown correctly on Linux hosts.
Thus, as a fix, if an ENOENT is thrown, an additional check is
performed to see whether the destination path indeed contains
a trailing slash, and if so, the errno is adjusted to ENOTDIR
to match the POSIX/WASI spec.
This commit is contained in:
Jakub Konka
2019-09-17 23:03:31 +02:00
parent 90f1cd5c96
commit d33036a3b5
5 changed files with 77 additions and 23 deletions

View File

@@ -207,26 +207,6 @@ pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize>
}
}
pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
use nix::libc::renameat;
let old_path_cstr = CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
let new_path_cstr = CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
let res = unsafe {
renameat(
resolved_old.dirfd().as_raw_fd(),
old_path_cstr.as_ptr(),
resolved_new.dirfd().as_raw_fd(),
new_path_cstr.as_ptr(),
)
};
if res != 0 {
Err(host_impl::errno_from_nix(nix::errno::Errno::last()))
} else {
Ok(())
}
}
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
use std::os::unix::fs::MetadataExt;