From cf5289c5530e29b501b849d874936e11b9c954d2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 5 Jul 2020 09:13:01 -0700 Subject: [PATCH] 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. --- crates/wasi-common/yanix/src/dir.rs | 3 ++ crates/wasi-common/yanix/src/fcntl.rs | 3 ++ crates/wasi-common/yanix/src/file.rs | 21 ++++++++---- crates/wasi-common/yanix/src/lib.rs | 5 ++- crates/wasi-common/yanix/src/sys/mod.rs | 3 ++ .../wasi-common/yanix/src/sys/wasi/fadvise.rs | 23 +++++++++++++ crates/wasi-common/yanix/src/sys/wasi/file.rs | 21 ++++++++++++ .../yanix/src/sys/wasi/filetime.rs | 33 +++++++++++++++++++ crates/wasi-common/yanix/src/sys/wasi/mod.rs | 3 ++ 9 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 crates/wasi-common/yanix/src/sys/wasi/fadvise.rs create mode 100644 crates/wasi-common/yanix/src/sys/wasi/file.rs create mode 100644 crates/wasi-common/yanix/src/sys/wasi/filetime.rs create mode 100644 crates/wasi-common/yanix/src/sys/wasi/mod.rs diff --git a/crates/wasi-common/yanix/src/dir.rs b/crates/wasi-common/yanix/src/dir.rs index 12b05686a6..50166a35b1 100644 --- a/crates/wasi-common/yanix/src/dir.rs +++ b/crates/wasi-common/yanix/src/dir.rs @@ -4,7 +4,10 @@ use crate::{ }; use std::convert::TryInto; use std::io::{Error, Result}; +#[cfg(unix)] 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}; pub use crate::sys::EntryExt; diff --git a/crates/wasi-common/yanix/src/fcntl.rs b/crates/wasi-common/yanix/src/fcntl.rs index 12c57cbd47..824b997b9b 100644 --- a/crates/wasi-common/yanix/src/fcntl.rs +++ b/crates/wasi-common/yanix/src/fcntl.rs @@ -3,7 +3,10 @@ use crate::{ from_result, from_success_code, }; use std::io::Result; +#[cfg(unix)] 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 { // Both fcntl commands expect a RawFd arg which will specify diff --git a/crates/wasi-common/yanix/src/file.rs b/crates/wasi-common/yanix/src/file.rs index c525ac444f..10f4aa6a05 100644 --- a/crates/wasi-common/yanix/src/file.rs +++ b/crates/wasi-common/yanix/src/file.rs @@ -1,11 +1,14 @@ use crate::{from_result, from_success_code}; use bitflags::bitflags; use cfg_if::cfg_if; +#[cfg(unix)] +use std::os::unix::prelude::*; +#[cfg(target_os = "wasi")] +use std::os::wasi::prelude::*; use std::{ convert::TryInto, ffi::{CString, OsStr, OsString}, io::Result, - os::unix::prelude::*, }; pub use crate::sys::file::*; @@ -62,6 +65,7 @@ bitflags! { target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "wasi", target_os = "emscripten"))] { libc::O_DSYNC } else if #[cfg(target_os = "freebsd")] { @@ -87,6 +91,7 @@ bitflags! { #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "wasi", target_os = "emscripten"))] const RSYNC = libc::O_RSYNC; const SYNC = libc::O_SYNC; @@ -189,11 +194,11 @@ pub unsafe fn mkdirat>(dirfd: RawFd, path: P, mode: Mode) -> Res from_success_code(libc::mkdirat(dirfd, path.as_ptr(), mode.bits())) } -pub unsafe fn linkat>( +pub unsafe fn linkat, Q: AsRef>( old_dirfd: RawFd, old_path: P, new_dirfd: RawFd, - new_path: P, + new_path: Q, flags: AtFlags, ) -> Result<()> { let old_path = CString::new(old_path.as_ref().as_bytes())?; @@ -212,11 +217,11 @@ pub unsafe fn unlinkat>(dirfd: RawFd, path: P, flags: AtFlags) - from_success_code(libc::unlinkat(dirfd, path.as_ptr(), flags.bits())) } -pub unsafe fn renameat>( +pub unsafe fn renameat, Q: AsRef>( old_dirfd: RawFd, old_path: P, new_dirfd: RawFd, - new_path: P, + 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())?; @@ -228,7 +233,11 @@ pub unsafe fn renameat>( )) } -pub unsafe fn symlinkat>(old_path: P, new_dirfd: RawFd, new_path: P) -> Result<()> { +pub unsafe fn symlinkat, Q: AsRef>( + 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())?; from_success_code(libc::symlinkat( diff --git a/crates/wasi-common/yanix/src/lib.rs b/crates/wasi-common/yanix/src/lib.rs index 955a809436..2b742c4e97 100644 --- a/crates/wasi-common/yanix/src/lib.rs +++ b/crates/wasi-common/yanix/src/lib.rs @@ -7,14 +7,17 @@ //! //! [nix]: https://github.com/nix-rust/nix //! [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 dir; pub mod fcntl; pub mod file; pub mod filetime; +#[cfg(not(target_os = "wasi"))] // not implemented for WASI in yanix yet pub mod poll; +#[cfg(not(target_os = "wasi"))] // not supported in WASI yet pub mod socket; mod sys; diff --git a/crates/wasi-common/yanix/src/sys/mod.rs b/crates/wasi-common/yanix/src/sys/mod.rs index e6bd0e36dc..c189768532 100644 --- a/crates/wasi-common/yanix/src/sys/mod.rs +++ b/crates/wasi-common/yanix/src/sys/mod.rs @@ -18,6 +18,9 @@ cfg_if! { target_os = "dragonfly"))] { mod bsd; pub(crate) use bsd::*; + } else if #[cfg(target_os = "wasi")] { + mod wasi; + pub(crate) use wasi::*; } else { compile_error!("yanix doesn't compile for this platform yet"); } diff --git a/crates/wasi-common/yanix/src/sys/wasi/fadvise.rs b/crates/wasi-common/yanix/src/sys/wasi/fadvise.rs new file mode 100644 index 0000000000..4c8d0fc4ad --- /dev/null +++ b/crates/wasi-common/yanix/src/sys/wasi/fadvise.rs @@ -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)) +} diff --git a/crates/wasi-common/yanix/src/sys/wasi/file.rs b/crates/wasi-common/yanix/src/sys/wasi/file.rs new file mode 100644 index 0000000000..4753d72f42 --- /dev/null +++ b/crates/wasi-common/yanix/src/sys/wasi/file.rs @@ -0,0 +1,21 @@ +use std::{ + io::{Error, Result}, + os::wasi::prelude::*, +}; + +pub unsafe fn isatty(fd: RawFd) -> Result { + 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) + } + } +} diff --git a/crates/wasi-common/yanix/src/sys/wasi/filetime.rs b/crates/wasi-common/yanix/src/sys/wasi/filetime.rs new file mode 100644 index 0000000000..7cd8a4483c --- /dev/null +++ b/crates/wasi-common/yanix/src/sys/wasi/filetime.rs @@ -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, + ) + }) +} diff --git a/crates/wasi-common/yanix/src/sys/wasi/mod.rs b/crates/wasi-common/yanix/src/sys/wasi/mod.rs new file mode 100644 index 0000000000..104da5e592 --- /dev/null +++ b/crates/wasi-common/yanix/src/sys/wasi/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod fadvise; +pub(crate) mod file; +pub(crate) mod filetime;