Begin porting yanix to WASI.

This isn't complete yet, but subsequent steps will depend on Rust libstd
and libc bindings changes that are in flight.
This commit is contained in:
Dan Gohman
2020-07-05 09:13:01 -07:00
committed by Jakub Konka
parent 25397d0c15
commit cf5289c553
9 changed files with 108 additions and 7 deletions

View File

@@ -4,7 +4,10 @@ use crate::{
}; };
use std::convert::TryInto; use std::convert::TryInto;
use std::io::{Error, Result}; use std::io::{Error, Result};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, IntoRawFd, RawFd};
use std::{ffi::CStr, io, ops::Deref, ptr}; use std::{ffi::CStr, io, ops::Deref, ptr};
pub use crate::sys::EntryExt; pub use crate::sys::EntryExt;

View File

@@ -3,7 +3,10 @@ use crate::{
from_result, from_success_code, from_result, from_success_code,
}; };
use std::io::Result; use std::io::Result;
#[cfg(unix)]
use std::os::unix::prelude::*; use std::os::unix::prelude::*;
#[cfg(target_os = "wasi")]
use std::os::wasi::prelude::*;
pub unsafe fn dup_fd(fd: RawFd, close_on_exec: bool) -> Result<RawFd> { pub unsafe fn dup_fd(fd: RawFd, close_on_exec: bool) -> Result<RawFd> {
// Both fcntl commands expect a RawFd arg which will specify // Both fcntl commands expect a RawFd arg which will specify

View File

@@ -1,11 +1,14 @@
use crate::{from_result, from_success_code}; use crate::{from_result, from_success_code};
use bitflags::bitflags; use bitflags::bitflags;
use cfg_if::cfg_if; use cfg_if::cfg_if;
#[cfg(unix)]
use std::os::unix::prelude::*;
#[cfg(target_os = "wasi")]
use std::os::wasi::prelude::*;
use std::{ use std::{
convert::TryInto, convert::TryInto,
ffi::{CString, OsStr, OsString}, ffi::{CString, OsStr, OsString},
io::Result, io::Result,
os::unix::prelude::*,
}; };
pub use crate::sys::file::*; pub use crate::sys::file::*;
@@ -62,6 +65,7 @@ bitflags! {
target_os = "macos", target_os = "macos",
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
target_os = "wasi",
target_os = "emscripten"))] { target_os = "emscripten"))] {
libc::O_DSYNC libc::O_DSYNC
} else if #[cfg(target_os = "freebsd")] { } else if #[cfg(target_os = "freebsd")] {
@@ -87,6 +91,7 @@ bitflags! {
#[cfg(any(target_os = "linux", #[cfg(any(target_os = "linux",
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
target_os = "wasi",
target_os = "emscripten"))] target_os = "emscripten"))]
const RSYNC = libc::O_RSYNC; const RSYNC = libc::O_RSYNC;
const SYNC = libc::O_SYNC; const SYNC = libc::O_SYNC;
@@ -189,11 +194,11 @@ pub unsafe fn mkdirat<P: AsRef<OsStr>>(dirfd: RawFd, path: P, mode: Mode) -> Res
from_success_code(libc::mkdirat(dirfd, path.as_ptr(), mode.bits())) from_success_code(libc::mkdirat(dirfd, path.as_ptr(), mode.bits()))
} }
pub unsafe fn linkat<P: AsRef<OsStr>>( pub unsafe fn linkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
old_dirfd: RawFd, old_dirfd: RawFd,
old_path: P, old_path: P,
new_dirfd: RawFd, new_dirfd: RawFd,
new_path: P, new_path: Q,
flags: AtFlags, flags: AtFlags,
) -> Result<()> { ) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?; let old_path = CString::new(old_path.as_ref().as_bytes())?;
@@ -212,11 +217,11 @@ pub unsafe fn unlinkat<P: AsRef<OsStr>>(dirfd: RawFd, path: P, flags: AtFlags) -
from_success_code(libc::unlinkat(dirfd, path.as_ptr(), flags.bits())) from_success_code(libc::unlinkat(dirfd, path.as_ptr(), flags.bits()))
} }
pub unsafe fn renameat<P: AsRef<OsStr>>( pub unsafe fn renameat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
old_dirfd: RawFd, old_dirfd: RawFd,
old_path: P, old_path: P,
new_dirfd: RawFd, new_dirfd: RawFd,
new_path: P, new_path: Q,
) -> Result<()> { ) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?; let old_path = CString::new(old_path.as_ref().as_bytes())?;
let new_path = CString::new(new_path.as_ref().as_bytes())?; let new_path = CString::new(new_path.as_ref().as_bytes())?;
@@ -228,7 +233,11 @@ pub unsafe fn renameat<P: AsRef<OsStr>>(
)) ))
} }
pub unsafe fn symlinkat<P: AsRef<OsStr>>(old_path: P, new_dirfd: RawFd, new_path: P) -> Result<()> { pub unsafe fn symlinkat<P: AsRef<OsStr>, Q: AsRef<OsStr>>(
old_path: P,
new_dirfd: RawFd,
new_path: Q,
) -> Result<()> {
let old_path = CString::new(old_path.as_ref().as_bytes())?; let old_path = CString::new(old_path.as_ref().as_bytes())?;
let new_path = CString::new(new_path.as_ref().as_bytes())?; let new_path = CString::new(new_path.as_ref().as_bytes())?;
from_success_code(libc::symlinkat( from_success_code(libc::symlinkat(

View File

@@ -7,14 +7,17 @@
//! //!
//! [nix]: https://github.com/nix-rust/nix //! [nix]: https://github.com/nix-rust/nix
//! [wasi-common]: https://github.com/bytecodealliance/wasmtime/tree/main/crates/wasi-common //! [wasi-common]: https://github.com/bytecodealliance/wasmtime/tree/main/crates/wasi-common
#![cfg(unix)] #![cfg(any(unix, target_os = "wasi"))]
#[cfg(not(target_os = "wasi"))] // not implemented for WASI in yanix yet
pub mod clock; pub mod clock;
pub mod dir; pub mod dir;
pub mod fcntl; pub mod fcntl;
pub mod file; pub mod file;
pub mod filetime; pub mod filetime;
#[cfg(not(target_os = "wasi"))] // not implemented for WASI in yanix yet
pub mod poll; pub mod poll;
#[cfg(not(target_os = "wasi"))] // not supported in WASI yet
pub mod socket; pub mod socket;
mod sys; mod sys;

View File

@@ -18,6 +18,9 @@ cfg_if! {
target_os = "dragonfly"))] { target_os = "dragonfly"))] {
mod bsd; mod bsd;
pub(crate) use bsd::*; pub(crate) use bsd::*;
} else if #[cfg(target_os = "wasi")] {
mod wasi;
pub(crate) use wasi::*;
} else { } else {
compile_error!("yanix doesn't compile for this platform yet"); compile_error!("yanix doesn't compile for this platform yet");
} }

View File

@@ -0,0 +1,23 @@
use crate::from_success_code;
use std::io::Result;
use std::os::wasi::prelude::*;
#[derive(Debug, Copy, Clone)]
#[repr(i32)]
pub enum PosixFadviseAdvice {
Normal = libc::POSIX_FADV_NORMAL,
Sequential = libc::POSIX_FADV_SEQUENTIAL,
Random = libc::POSIX_FADV_RANDOM,
NoReuse = libc::POSIX_FADV_NOREUSE,
WillNeed = libc::POSIX_FADV_WILLNEED,
DontNeed = libc::POSIX_FADV_DONTNEED,
}
pub unsafe fn posix_fadvise(
fd: RawFd,
offset: libc::off_t,
len: libc::off_t,
advice: PosixFadviseAdvice,
) -> Result<()> {
from_success_code(libc::posix_fadvise(fd, offset, len, advice as libc::c_int))
}

View File

@@ -0,0 +1,21 @@
use std::{
io::{Error, Result},
os::wasi::prelude::*,
};
pub unsafe fn isatty(fd: RawFd) -> Result<bool> {
let res = libc::isatty(fd);
if res == 1 {
// isatty() returns 1 if fd is an open file descriptor referring to a terminal...
Ok(true)
} else {
// ... otherwise 0 is returned, and errno is set to indicate the error.
let errno = Error::last_os_error();
let raw_errno = errno.raw_os_error().unwrap();
if raw_errno == libc::ENOTTY {
Ok(false)
} else {
Err(errno)
}
}
}

View File

@@ -0,0 +1,33 @@
use crate::filetime::FileTime;
use crate::from_success_code;
use std::fs::File;
use std::io;
pub fn utimensat(
dirfd: &File,
path: &str,
atime: FileTime,
mtime: FileTime,
symlink_nofollow: bool,
) -> io::Result<()> {
use crate::filetime::to_timespec;
use std::ffi::CString;
use std::os::wasi::prelude::*;
let p = CString::new(path.as_bytes())?;
let times = [to_timespec(&atime)?, to_timespec(&mtime)?];
let flags = if symlink_nofollow {
libc::AT_SYMLINK_NOFOLLOW
} else {
0
};
from_success_code(unsafe {
libc::utimensat(
dirfd.as_raw_fd() as libc::c_int,
p.as_ptr(),
times.as_ptr(),
flags,
)
})
}

View File

@@ -0,0 +1,3 @@
pub(crate) mod fadvise;
pub(crate) mod file;
pub(crate) mod filetime;