Revert fstatat on *nix and test symlinks in path_filestat calls (#1725)
* Revert fstatat on *nix and test symlinks in path_filestat calls
This commit effectively reverts too eager refactoring on my part which
resulted in incorrect `path_filestat_{get, set_times}` behaviour on
*nix hosts. In the presence of symlinks, neither of the calls would
work properly.
In order to shield ourselves from similar errors in the future, I've
augmented the `path_filestat` test cases with symlink checks as well.
* Pass appropriate flags to fstatat and utimensat
* Fix formatting
* Fix Windows build
* Expand final symlinks if follow is set on Windows
* Fix formatting
* Do not follow symlinks unless specified on Windows
* Update comments and restart CI
* Skip testing volatile atim field
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::handle::{Handle, HandleRights};
|
||||
use crate::sys::osdir::OsDir;
|
||||
use crate::sys::AsFile;
|
||||
use crate::sys::{fd, AsFile};
|
||||
use crate::wasi::{types, Errno, Result};
|
||||
use std::convert::TryFrom;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
@@ -494,3 +494,42 @@ pub(crate) fn remove_directory(dirfd: &OsDir, path: &str) -> Result<()> {
|
||||
let path = concatenate(dirfd, path)?;
|
||||
std::fs::remove_dir(&path).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn filestat_get_at(dirfd: &OsDir, path: &str, follow: bool) -> Result<types::Filestat> {
|
||||
use winx::file::Flags;
|
||||
let path = concatenate(dirfd, path)?;
|
||||
let mut opts = OpenOptions::new();
|
||||
|
||||
if !follow {
|
||||
// By specifying FILE_FLAG_OPEN_REPARSE_POINT, we force Windows to *not* dereference symlinks.
|
||||
opts.custom_flags(Flags::FILE_FLAG_OPEN_REPARSE_POINT.bits());
|
||||
}
|
||||
|
||||
let file = opts.read(true).open(path)?;
|
||||
let stat = fd::filestat_get(&file)?;
|
||||
Ok(stat)
|
||||
}
|
||||
|
||||
pub(crate) fn filestat_set_times_at(
|
||||
dirfd: &OsDir,
|
||||
path: &str,
|
||||
atim: types::Timestamp,
|
||||
mtim: types::Timestamp,
|
||||
fst_flags: types::Fstflags,
|
||||
follow: bool,
|
||||
) -> Result<()> {
|
||||
use winx::file::{AccessMode, Flags};
|
||||
let path = concatenate(dirfd, path)?;
|
||||
let mut opts = OpenOptions::new();
|
||||
|
||||
if !follow {
|
||||
// By specifying FILE_FLAG_OPEN_REPARSE_POINT, we force Windows to *not* dereference symlinks.
|
||||
opts.custom_flags(Flags::FILE_FLAG_OPEN_REPARSE_POINT.bits());
|
||||
}
|
||||
|
||||
let file = opts
|
||||
.access_mode(AccessMode::FILE_WRITE_ATTRIBUTES.bits())
|
||||
.open(path)?;
|
||||
fd::filestat_set_times(&file, atim, mtim, fst_flags)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user