* Dynamically load utimensat if exists on the host This commit introduces a change to file time management for *nix based hosts in that it firstly tries to load `utimensat` symbol, and if it doesn't exist, then falls back to `utimes` instead. This change is borrowing very heavily from [filetime] crate, however, it introduces a couple of helpers and methods specific to WASI use case (or more generally, to a use case which requires modifying times of entities specified by a pair `(DirFD, RelativePath)` rather than the typical file time specification based only absolute path or raw file descriptor as is the case with [filetime] crate. The trick here is, that on kernels which do not have `utimensat` symbol, this implementation emulates this behaviour by a combination of `openat` and `utimes`. This commit also is meant to address #516. [filetime]: https://github.com/alexcrichton/filetime * Fix symlink NOFOLLOW flag setting * Add docs and specify UTIME_NOW/OMIT on Linux Previously, we relied on [libc] crate for `UTIME_NOW` and `UTIME_OMIT` constants on Linux. However, following the convention assumed in [filetime] crate, this is now changed to directly specified by us in our crate. [libc]: https://github.com/rust-lang/libc [filetime]: https://github.com/alexcrichton/filetime * Refactor UTIME_NOW/OMIT for BSD * Address final discussion points
40 lines
829 B
Rust
40 lines
829 B
Rust
pub(crate) mod fdentry_impl;
|
|
pub(crate) mod host_impl;
|
|
pub(crate) mod hostcalls_impl;
|
|
|
|
mod dir;
|
|
mod filetime;
|
|
|
|
#[cfg(any(
|
|
target_os = "macos",
|
|
target_os = "netbsd",
|
|
target_os = "freebsd",
|
|
target_os = "openbsd",
|
|
target_os = "ios",
|
|
target_os = "dragonfly"
|
|
))]
|
|
mod bsd;
|
|
#[cfg(target_os = "linux")]
|
|
mod linux;
|
|
|
|
use crate::{Error, Result};
|
|
use std::ffi::CString;
|
|
use std::fs::{File, OpenOptions};
|
|
use std::path::Path;
|
|
|
|
pub(crate) fn dev_null() -> Result<File> {
|
|
OpenOptions::new()
|
|
.read(true)
|
|
.write(true)
|
|
.open("/dev/null")
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
pub(crate) fn str_to_cstring(s: &str) -> Result<CString> {
|
|
CString::new(s.as_bytes()).map_err(|_| Error::EILSEQ)
|
|
}
|
|
|
|
pub fn preopen_dir<P: AsRef<Path>>(path: P) -> Result<File> {
|
|
File::open(path).map_err(Into::into)
|
|
}
|