diff options
Diffstat (limited to 'library/std/src/sys/wasi')
-rw-r--r-- | library/std/src/sys/wasi/fs.rs | 105 | ||||
-rw-r--r-- | library/std/src/sys/wasi/io.rs | 6 | ||||
-rw-r--r-- | library/std/src/sys/wasi/mod.rs | 3 | ||||
-rw-r--r-- | library/std/src/sys/wasi/os.rs | 81 | ||||
-rw-r--r-- | library/std/src/sys/wasi/stdio.rs | 23 | ||||
-rw-r--r-- | library/std/src/sys/wasi/time.rs | 4 |
6 files changed, 115 insertions, 107 deletions
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 510cf36b1..d4866bbc3 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -1,7 +1,7 @@ #![deny(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; -use crate::ffi::{CStr, CString, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::iter; @@ -12,6 +12,7 @@ use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd use crate::path::{Path, PathBuf}; use crate::ptr; use crate::sync::Arc; +use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -65,8 +66,8 @@ pub struct FilePermissions { #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes { - accessed: Option<wasi::Timestamp>, - modified: Option<wasi::Timestamp>, + accessed: Option<SystemTime>, + modified: Option<SystemTime>, } #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] @@ -120,11 +121,11 @@ impl FilePermissions { impl FileTimes { pub fn set_accessed(&mut self, t: SystemTime) { - self.accessed = Some(t.to_wasi_timestamp_or_panic()); + self.accessed = Some(t); } pub fn set_modified(&mut self, t: SystemTime) { - self.modified = Some(t.to_wasi_timestamp_or_panic()); + self.modified = Some(t); } } @@ -476,9 +477,16 @@ impl File { } pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + let to_timestamp = |time: Option<SystemTime>| { + match time { + Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts), + Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")), + None => Ok(0), + } + }; self.fd.filestat_set_times( - times.accessed.unwrap_or(0), - times.modified.unwrap_or(0), + to_timestamp(times.accessed)?, + to_timestamp(times.modified)?, times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM) | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM), ) @@ -687,51 +695,52 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> { /// Note that this can fail if `p` doesn't look like it can be opened relative /// to any pre-opened file descriptor. fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { - let p = CString::new(p.as_os_str().as_bytes())?; - let mut buf = Vec::<u8>::with_capacity(512); - loop { - unsafe { - let mut relative_path = buf.as_ptr().cast(); - let mut abs_prefix = ptr::null(); - let fd = __wasilibc_find_relpath( - p.as_ptr(), - &mut abs_prefix, - &mut relative_path, - buf.capacity(), - ); - if fd == -1 { - if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) { - // Trigger the internal buffer resizing logic of `Vec` by requiring - // more space than the current capacity. - let cap = buf.capacity(); - buf.set_len(cap); - buf.reserve(1); - continue; - } - let msg = format!( - "failed to find a pre-opened file descriptor \ - through which {:?} could be opened", - p + run_path_with_cstr(p, |p| { + let mut buf = Vec::<u8>::with_capacity(512); + loop { + unsafe { + let mut relative_path = buf.as_ptr().cast(); + let mut abs_prefix = ptr::null(); + let fd = __wasilibc_find_relpath( + p.as_ptr(), + &mut abs_prefix, + &mut relative_path, + buf.capacity(), ); - return Err(io::Error::new(io::ErrorKind::Uncategorized, msg)); - } - let relative = CStr::from_ptr(relative_path).to_bytes().to_vec(); + if fd == -1 { + if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) { + // Trigger the internal buffer resizing logic of `Vec` by requiring + // more space than the current capacity. + let cap = buf.capacity(); + buf.set_len(cap); + buf.reserve(1); + continue; + } + let msg = format!( + "failed to find a pre-opened file descriptor \ + through which {:?} could be opened", + p + ); + return Err(io::Error::new(io::ErrorKind::Uncategorized, msg)); + } + let relative = CStr::from_ptr(relative_path).to_bytes().to_vec(); - return Ok(( - ManuallyDrop::new(WasiFd::from_raw_fd(fd as c_int)), - PathBuf::from(OsString::from_vec(relative)), - )); + return Ok(( + ManuallyDrop::new(WasiFd::from_raw_fd(fd as c_int)), + PathBuf::from(OsString::from_vec(relative)), + )); + } } - } - extern "C" { - pub fn __wasilibc_find_relpath( - path: *const libc::c_char, - abs_prefix: *mut *const libc::c_char, - relative_path: *mut *const libc::c_char, - relative_path_len: libc::size_t, - ) -> libc::c_int; - } + extern "C" { + pub fn __wasilibc_find_relpath( + path: *const libc::c_char, + abs_prefix: *mut *const libc::c_char, + relative_path: *mut *const libc::c_char, + relative_path_len: libc::size_t, + ) -> libc::c_int; + } + }) } pub fn osstr2str(f: &OsStr) -> io::Result<&str> { diff --git a/library/std/src/sys/wasi/io.rs b/library/std/src/sys/wasi/io.rs index ee017d13a..2cd45df88 100644 --- a/library/std/src/sys/wasi/io.rs +++ b/library/std/src/sys/wasi/io.rs @@ -1,6 +1,7 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::marker::PhantomData; +use crate::os::fd::{AsFd, AsRawFd}; use crate::slice; #[derive(Copy, Clone)] @@ -71,3 +72,8 @@ impl<'a> IoSliceMut<'a> { unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) } } } + +pub fn is_terminal(fd: &impl AsFd) -> bool { + let fd = fd.as_fd(); + unsafe { libc::isatty(fd.as_raw_fd()) != 0 } +} diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index 683a07a34..c8c47763a 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -25,6 +25,9 @@ pub mod cmath; pub mod env; pub mod fd; pub mod fs; +#[allow(unused)] +#[path = "../wasm/atomics/futex.rs"] +pub mod futex; pub mod io; #[path = "../unsupported/locks/mod.rs"] pub mod locks; diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs index c5229a188..f5513e999 100644 --- a/library/std/src/sys/wasi/os.rs +++ b/library/std/src/sys/wasi/os.rs @@ -1,14 +1,15 @@ #![deny(unsafe_op_in_unsafe_fn)] -use crate::any::Any; use crate::error::Error as StdError; -use crate::ffi::{CStr, CString, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; +use crate::ops::Drop; use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; use crate::str; +use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr}; use crate::sys::memchr; use crate::sys::unsupported; use crate::vec; @@ -23,10 +24,26 @@ mod libc { } } -#[cfg(not(target_feature = "atomics"))] -pub unsafe fn env_lock() -> impl Any { - // No need for a lock if we're single-threaded, but this function will need - // to get implemented for multi-threaded scenarios +cfg_if::cfg_if! { + if #[cfg(target_feature = "atomics")] { + // Access to the environment must be protected by a lock in multi-threaded scenarios. + use crate::sync::{PoisonError, RwLock}; + static ENV_LOCK: RwLock<()> = RwLock::new(()); + pub fn env_read_lock() -> impl Drop { + ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner) + } + pub fn env_write_lock() -> impl Drop { + ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner) + } + } else { + // No need for a lock if we are single-threaded. + pub fn env_read_lock() -> impl Drop { + Box::new(()) + } + pub fn env_write_lock() -> impl Drop { + Box::new(()) + } + } } pub fn errno() -> i32 { @@ -77,13 +94,10 @@ pub fn getcwd() -> io::Result<PathBuf> { } pub fn chdir(p: &path::Path) -> io::Result<()> { - let p: &OsStr = p.as_ref(); - let p = CString::new(p.as_bytes())?; - unsafe { - match libc::chdir(p.as_ptr()) == (0 as libc::c_int) { - true => Ok(()), - false => Err(io::Error::last_os_error()), - } + let result = run_path_with_cstr(p, |p| unsafe { Ok(libc::chdir(p.as_ptr())) })?; + match result == (0 as libc::c_int) { + true => Ok(()), + false => Err(io::Error::last_os_error()), } } @@ -146,7 +160,7 @@ impl Iterator for Env { pub fn env() -> Env { unsafe { - let _guard = env_lock(); + let _guard = env_read_lock(); let mut environ = libc::environ; let mut result = Vec::new(); if !environ.is_null() { @@ -176,35 +190,32 @@ pub fn env() -> Env { } pub fn getenv(k: &OsStr) -> Option<OsString> { - let k = CString::new(k.as_bytes()).ok()?; - unsafe { - let _guard = env_lock(); - let s = libc::getenv(k.as_ptr()) as *const libc::c_char; - if s.is_null() { - None - } else { - Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec())) - } + let s = run_with_cstr(k.as_bytes(), |k| unsafe { + let _guard = env_read_lock(); + Ok(libc::getenv(k.as_ptr()) as *const libc::c_char) + }) + .ok()?; + if s.is_null() { + None + } else { + Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec())) } } pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { - let k = CString::new(k.as_bytes())?; - let v = CString::new(v.as_bytes())?; - - unsafe { - let _guard = env_lock(); - cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop) - } + run_with_cstr(k.as_bytes(), |k| { + run_with_cstr(v.as_bytes(), |v| unsafe { + let _guard = env_write_lock(); + cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop) + }) + }) } pub fn unsetenv(n: &OsStr) -> io::Result<()> { - let nbuf = CString::new(n.as_bytes())?; - - unsafe { - let _guard = env_lock(); + run_with_cstr(n.as_bytes(), |nbuf| unsafe { + let _guard = env_write_lock(); cvt(libc::unsetenv(nbuf.as_ptr())).map(drop) - } + }) } pub fn temp_dir() -> PathBuf { diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs index d2081771b..4cc0e4ed5 100644 --- a/library/std/src/sys/wasi/stdio.rs +++ b/library/std/src/sys/wasi/stdio.rs @@ -4,7 +4,7 @@ use super::fd::WasiFd; use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::os::raw; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd}; +use crate::os::wasi::io::{AsRawFd, FromRawFd}; pub struct Stdin; pub struct Stdout; @@ -23,13 +23,6 @@ impl AsRawFd for Stdin { } } -impl AsFd for Stdin { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(0) } - } -} - impl io::Read for Stdin { fn read(&mut self, data: &mut [u8]) -> io::Result<usize> { self.read_vectored(&mut [IoSliceMut::new(data)]) @@ -58,13 +51,6 @@ impl AsRawFd for Stdout { } } -impl AsFd for Stdout { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(1) } - } -} - impl io::Write for Stdout { fn write(&mut self, data: &[u8]) -> io::Result<usize> { self.write_vectored(&[IoSlice::new(data)]) @@ -96,13 +82,6 @@ impl AsRawFd for Stderr { } } -impl AsFd for Stderr { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(2) } - } -} - impl io::Write for Stderr { fn write(&mut self, data: &[u8]) -> io::Result<usize> { self.write_vectored(&[IoSlice::new(data)]) diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs index 3d326e491..016b06efb 100644 --- a/library/std/src/sys/wasi/time.rs +++ b/library/std/src/sys/wasi/time.rs @@ -47,8 +47,8 @@ impl SystemTime { SystemTime(Duration::from_nanos(ts)) } - pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp { - self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp") + pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { + self.0.as_nanos().try_into().ok() } pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { |