Browse Source

Use AsRef<Path> instead of AsRef<OsStr> in yanix functions (#1950)

* Use AsRef<Path> instead of AsRef<OsStr> in yanix functions.

`AsRef<Path>` makes these more consistent with `std` interfaces, making
them easier to use outside of wasi-common.

Also, refactor the conversion to `CString` into a helper function.

* Reduce clutter from fully-qualifying names.

* rustfmt
pull/2047/head
Dan Gohman 4 years ago
committed by GitHub
parent
commit
4c15a4daf2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      crates/wasi-common/yanix/src/file.rs
  2. 16
      crates/wasi-common/yanix/src/lib.rs
  3. 7
      crates/wasi-common/yanix/src/sys/bsd/filetime.rs
  4. 7
      crates/wasi-common/yanix/src/sys/emscripten/filetime.rs
  5. 7
      crates/wasi-common/yanix/src/sys/linux/filetime.rs
  6. 7
      crates/wasi-common/yanix/src/sys/linux/utimesat.rs

47
crates/wasi-common/yanix/src/file.rs

@ -1,4 +1,4 @@
use crate::{from_result, from_success_code};
use crate::{cstr, from_result, from_success_code};
use bitflags::bitflags;
use cfg_if::cfg_if;
#[cfg(unix)]
@ -7,8 +7,9 @@ use std::os::unix::prelude::*;
use std::os::wasi::prelude::*;
use std::{
convert::TryInto,
ffi::{CString, OsStr, OsString},
ffi::{OsStr, OsString},
io::Result,
path::Path,
};
pub use crate::sys::file::*;
@ -157,13 +158,13 @@ impl FileType {
}
}
pub unsafe fn openat<P: AsRef<OsStr>>(
pub unsafe fn openat<P: AsRef<Path>>(
dirfd: RawFd,
path: P,
oflag: OFlags,
mode: Mode,
) -> Result<RawFd> {
let path = CString::new(path.as_ref().as_bytes())?;
let path = cstr(path)?;
from_result(libc::openat(
dirfd,
path.as_ptr(),
@ -172,8 +173,8 @@ pub unsafe fn openat<P: AsRef<OsStr>>(
))
}
pub unsafe fn readlinkat<P: AsRef<OsStr>>(dirfd: RawFd, path: P) -> Result<OsString> {
let path = CString::new(path.as_ref().as_bytes())?;
pub unsafe fn readlinkat<P: AsRef<Path>>(dirfd: RawFd, path: P) -> Result<OsString> {
let path = cstr(path)?;
let buffer = &mut [0u8; libc::PATH_MAX as usize + 1];
let nread = from_result(libc::readlinkat(
dirfd,
@ -189,20 +190,20 @@ pub unsafe fn readlinkat<P: AsRef<OsStr>>(dirfd: RawFd, path: P) -> Result<OsStr
Ok(link.into())
}
pub unsafe fn mkdirat<P: AsRef<OsStr>>(dirfd: RawFd, path: P, mode: Mode) -> Result<()> {
let path = CString::new(path.as_ref().as_bytes())?;
pub unsafe fn mkdirat<P: AsRef<Path>>(dirfd: RawFd, path: P, mode: Mode) -> Result<()> {
let path = cstr(path)?;
from_success_code(libc::mkdirat(dirfd, path.as_ptr(), mode.bits()))
}
pub unsafe fn linkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
pub unsafe fn linkat<P: AsRef<Path>, Q: AsRef<Path>>(
old_dirfd: RawFd,
old_path: P,
new_dirfd: RawFd,
new_path: Q,
flags: AtFlags,
) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?;
let new_path = CString::new(new_path.as_ref().as_bytes())?;
let old_path = cstr(old_path)?;
let new_path = cstr(new_path)?;
from_success_code(libc::linkat(
old_dirfd,
old_path.as_ptr(),
@ -212,19 +213,19 @@ pub unsafe fn linkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
))
}
pub unsafe fn unlinkat<P: AsRef<OsStr>>(dirfd: RawFd, path: P, flags: AtFlags) -> Result<()> {
let path = CString::new(path.as_ref().as_bytes())?;
pub unsafe fn unlinkat<P: AsRef<Path>>(dirfd: RawFd, path: P, flags: AtFlags) -> Result<()> {
let path = cstr(path)?;
from_success_code(libc::unlinkat(dirfd, path.as_ptr(), flags.bits()))
}
pub unsafe fn renameat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
pub unsafe fn renameat<P: AsRef<Path>, Q: AsRef<Path>>(
old_dirfd: RawFd,
old_path: P,
new_dirfd: RawFd,
new_path: Q,
) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?;
let new_path = CString::new(new_path.as_ref().as_bytes())?;
let old_path = cstr(old_path)?;
let new_path = cstr(new_path)?;
from_success_code(libc::renameat(
old_dirfd,
old_path.as_ptr(),
@ -233,13 +234,13 @@ pub unsafe fn renameat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
))
}
pub unsafe fn symlinkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
pub unsafe fn symlinkat<P: AsRef<Path>, Q: AsRef<Path>>(
old_path: P,
new_dirfd: RawFd,
new_path: Q,
) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?;
let new_path = CString::new(new_path.as_ref().as_bytes())?;
let old_path = cstr(old_path)?;
let new_path = cstr(new_path)?;
from_success_code(libc::symlinkat(
old_path.as_ptr(),
new_dirfd,
@ -247,13 +248,9 @@ pub unsafe fn symlinkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
))
}
pub unsafe fn fstatat<P: AsRef<OsStr>>(
dirfd: RawFd,
path: P,
flags: AtFlags,
) -> Result<libc::stat> {
pub unsafe fn fstatat<P: AsRef<Path>>(dirfd: RawFd, path: P, flags: AtFlags) -> Result<libc::stat> {
use std::mem::MaybeUninit;
let path = CString::new(path.as_ref().as_bytes())?;
let path = cstr(path)?;
let mut filestat = MaybeUninit::<libc::stat>::uninit();
from_result(libc::fstatat(
dirfd,

16
crates/wasi-common/yanix/src/lib.rs

@ -26,7 +26,9 @@ pub mod fadvise {
pub use super::sys::fadvise::*;
}
use std::ffi::CString;
use std::io::{Error, Result};
use std::path::Path;
fn from_success_code<T: IsZero>(t: T) -> Result<()> {
if t.is_zero() {
@ -71,3 +73,17 @@ macro_rules! impl_is_minus_one {
}
impl_is_minus_one! { i32 i64 isize }
/// Convert an `AsRef<Path>` into a `CString`.
fn cstr<P: AsRef<Path>>(path: P) -> Result<CString> {
#[cfg(target_os = "hermit")]
use std::os::hermit::ext::ffi::OsStrExt;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
#[cfg(target_os = "vxworks")]
use std::os::vxworks::ext::ffi::OsStrExt;
#[cfg(target_os = "wasi")]
use std::os::wasi::ffi::OsStrExt;
Ok(CString::new(path.as_ref().as_os_str().as_bytes())?)
}

7
crates/wasi-common/yanix/src/sys/bsd/filetime.rs

@ -1,7 +1,7 @@
//! This module consists of helper types and functions for dealing
//! with setting the file times specific to BSD-style *nixes.
use crate::filetime::FileTime;
use crate::from_success_code;
use crate::{cstr, from_success_code};
use std::ffi::CStr;
use std::fs::File;
use std::io::Result;
@ -21,7 +21,6 @@ pub fn utimensat(
symlink_nofollow: bool,
) -> Result<()> {
use crate::filetime::to_timespec;
use std::ffi::CString;
use std::os::unix::prelude::*;
// Attempt to use the `utimensat` syscall, but if it's not supported by the
@ -33,10 +32,10 @@ pub fn utimensat(
0
};
let p = CString::new(path.as_bytes())?;
let path = cstr(path)?;
let times = [to_timespec(&atime)?, to_timespec(&mtime)?];
return from_success_code(unsafe {
func(dirfd.as_raw_fd(), p.as_ptr(), times.as_ptr(), flags)
func(dirfd.as_raw_fd(), path.as_ptr(), times.as_ptr(), flags)
});
}

7
crates/wasi-common/yanix/src/sys/emscripten/filetime.rs

@ -1,7 +1,7 @@
//! This module consists of helper types and functions for dealing
//! with setting the file times specific to Emscripten.
use crate::filetime::FileTime;
use crate::from_success_code;
use crate::{cstr, from_success_code};
use std::fs::File;
use std::io::Result;
@ -15,7 +15,6 @@ pub fn utimensat(
symlink_nofollow: bool,
) -> Result<()> {
use crate::filetime::to_timespec;
use std::ffi::CString;
use std::os::unix::prelude::*;
let flags = if symlink_nofollow {
@ -23,9 +22,9 @@ pub fn utimensat(
} else {
0
};
let p = CString::new(path.as_bytes())?;
let path = cstr(path)?;
let times = [to_timespec(&atime)?, to_timespec(&mtime)?];
from_success_code(unsafe {
libc::utimensat(dirfd.as_raw_fd(), p.as_ptr(), times.as_ptr(), flags)
libc::utimensat(dirfd.as_raw_fd(), path.as_ptr(), times.as_ptr(), flags)
})
}

7
crates/wasi-common/yanix/src/sys/linux/filetime.rs

@ -1,7 +1,7 @@
//! This module consists of helper types and functions for dealing
//! with setting the file times specific to Linux.
use crate::filetime::FileTime;
use crate::from_success_code;
use crate::{cstr, from_success_code};
use std::fs::File;
use std::io::Result;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
@ -20,7 +20,6 @@ pub fn utimensat(
symlink_nofollow: bool,
) -> Result<()> {
use crate::filetime::to_timespec;
use std::ffi::CString;
use std::os::unix::prelude::*;
let flags = if symlink_nofollow {
@ -33,13 +32,13 @@ pub fn utimensat(
// current kernel then fall back to an older syscall.
static INVALID: AtomicBool = AtomicBool::new(false);
if !INVALID.load(Relaxed) {
let p = CString::new(path.as_bytes())?;
let path = cstr(path)?;
let times = [to_timespec(&atime)?, to_timespec(&mtime)?];
let res = from_success_code(unsafe {
libc::syscall(
libc::SYS_utimensat,
dirfd.as_raw_fd(),
p.as_ptr(),
path.as_ptr(),
times.as_ptr(),
flags,
)

7
crates/wasi-common/yanix/src/sys/linux/utimesat.rs

@ -1,6 +1,6 @@
use crate::filetime::FileTime;
use crate::filetime::FileTimeExt;
use crate::from_success_code;
use crate::{cstr, from_success_code};
use std::fs;
use std::io::Result;
@ -15,16 +15,15 @@ pub fn utimesat(
mtime: FileTime,
symlink_nofollow: bool,
) -> Result<()> {
use std::ffi::CString;
use std::os::unix::prelude::*;
// emulate *at syscall by reading the path from a combination of
// (fd, path)
let p = CString::new(path.as_bytes())?;
let path = cstr(path)?;
let mut flags = libc::O_RDWR;
if symlink_nofollow {
flags |= libc::O_NOFOLLOW;
}
let fd = unsafe { libc::openat(dirfd.as_raw_fd(), p.as_ptr(), flags) };
let fd = unsafe { libc::openat(dirfd.as_raw_fd(), path.as_ptr(), flags) };
let f = unsafe { fs::File::from_raw_fd(fd) };
let (atime, mtime) = get_times(atime, mtime, || f.metadata().map_err(Into::into))?;
let times = [to_timeval(atime)?, to_timeval(mtime)?];

Loading…
Cancel
Save