Make wasi-common-std-sync's dependency on system-interface private. (#4784)
* Make wasi-common-std-sync's dependency on system-interface private. Change some `pub` functions which exposed system-interface types to be non-`pub`. And, change `from_sysif_fdflags` functions to `get_fd_flags` functions that take `impl AsFilelike` arguments instead of system-interface types. With these changes, system-interface is no longer exposed in the public API. * Add a public API for `is_read_write` too. Implementors using types implementing `AsFilelike` may want to use the same `is_read_write` logic, without explicitly depending on system-interface, so provide a function that provides that.
This commit is contained in:
@@ -31,6 +31,7 @@ rustix = { version = "0.35.6", features = ["fs"] }
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
once_cell = "1.12.0"
|
||||
io-extras = "0.15.0"
|
||||
rustix = { version = "0.35.6", features = ["net"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows-sys]
|
||||
version = "0.36.0"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use cap_fs_ext::MetadataExt;
|
||||
use fs_set_times::{SetTimes, SystemTimeSpec};
|
||||
use io_lifetimes::AsFilelike;
|
||||
use is_terminal::IsTerminal;
|
||||
use std::any::Any;
|
||||
use std::convert::TryInto;
|
||||
@@ -48,8 +49,8 @@ impl WasiFile for File {
|
||||
Ok(filetype_from(&meta.file_type()))
|
||||
}
|
||||
async fn get_fdflags(&mut self) -> Result<FdFlags, Error> {
|
||||
let fdflags = self.0.get_fd_flags()?;
|
||||
Ok(from_sysif_fdflags(fdflags))
|
||||
let fdflags = get_fd_flags(&self.0)?;
|
||||
Ok(fdflags)
|
||||
}
|
||||
async fn set_fdflags(&mut self, fdflags: FdFlags) -> Result<(), Error> {
|
||||
if fdflags.intersects(
|
||||
@@ -187,7 +188,10 @@ impl AsFd for File {
|
||||
self.0.as_fd()
|
||||
}
|
||||
}
|
||||
pub fn convert_systimespec(t: Option<wasi_common::SystemTimeSpec>) -> Option<SystemTimeSpec> {
|
||||
|
||||
pub(crate) fn convert_systimespec(
|
||||
t: Option<wasi_common::SystemTimeSpec>,
|
||||
) -> Option<SystemTimeSpec> {
|
||||
match t {
|
||||
Some(wasi_common::SystemTimeSpec::Absolute(t)) => {
|
||||
Some(SystemTimeSpec::Absolute(t.into_std()))
|
||||
@@ -197,7 +201,7 @@ pub fn convert_systimespec(t: Option<wasi_common::SystemTimeSpec>) -> Option<Sys
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_sysif_fdflags(f: wasi_common::file::FdFlags) -> system_interface::fs::FdFlags {
|
||||
pub(crate) fn to_sysif_fdflags(f: wasi_common::file::FdFlags) -> system_interface::fs::FdFlags {
|
||||
let mut out = system_interface::fs::FdFlags::empty();
|
||||
if f.contains(wasi_common::file::FdFlags::APPEND) {
|
||||
out |= system_interface::fs::FdFlags::APPEND;
|
||||
@@ -216,7 +220,12 @@ pub fn to_sysif_fdflags(f: wasi_common::file::FdFlags) -> system_interface::fs::
|
||||
}
|
||||
out
|
||||
}
|
||||
pub fn from_sysif_fdflags(f: system_interface::fs::FdFlags) -> wasi_common::file::FdFlags {
|
||||
|
||||
/// Return the file-descriptor flags for a given file-like object.
|
||||
///
|
||||
/// This returns the flags needed to implement [`WasiFile::get_fdflags`].
|
||||
pub fn get_fd_flags<Filelike: AsFilelike>(f: Filelike) -> io::Result<wasi_common::file::FdFlags> {
|
||||
let f = f.as_filelike().get_fd_flags()?;
|
||||
let mut out = wasi_common::file::FdFlags::empty();
|
||||
if f.contains(system_interface::fs::FdFlags::APPEND) {
|
||||
out |= wasi_common::file::FdFlags::APPEND;
|
||||
@@ -233,9 +242,10 @@ pub fn from_sysif_fdflags(f: system_interface::fs::FdFlags) -> wasi_common::file
|
||||
if f.contains(system_interface::fs::FdFlags::SYNC) {
|
||||
out |= wasi_common::file::FdFlags::SYNC;
|
||||
}
|
||||
out
|
||||
Ok(out)
|
||||
}
|
||||
pub fn convert_advice(advice: Advice) -> system_interface::fs::Advice {
|
||||
|
||||
fn convert_advice(advice: Advice) -> system_interface::fs::Advice {
|
||||
match advice {
|
||||
Advice::Normal => system_interface::fs::Advice::Normal,
|
||||
Advice::Sequential => system_interface::fs::Advice::Sequential,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#[cfg(windows)]
|
||||
use io_extras::os::windows::{AsRawHandleOrSocket, RawHandleOrSocket};
|
||||
#[cfg(unix)]
|
||||
use io_lifetimes::AsFilelike;
|
||||
use io_lifetimes::AsSocketlike;
|
||||
#[cfg(unix)]
|
||||
use io_lifetimes::{AsFd, BorrowedFd};
|
||||
@@ -105,8 +103,8 @@ macro_rules! wasi_listen_write_impl {
|
||||
}
|
||||
#[cfg(unix)]
|
||||
async fn get_fdflags(&mut self) -> Result<FdFlags, Error> {
|
||||
let fdflags = self.0.as_filelike().get_fd_flags()?;
|
||||
Ok(from_sysif_fdflags(fdflags))
|
||||
let fdflags = get_fd_flags(&self.0)?;
|
||||
Ok(fdflags)
|
||||
}
|
||||
async fn set_fdflags(&mut self, fdflags: FdFlags) -> Result<(), Error> {
|
||||
if fdflags == wasi_common::file::FdFlags::NONBLOCK {
|
||||
@@ -193,8 +191,8 @@ macro_rules! wasi_stream_write_impl {
|
||||
}
|
||||
#[cfg(unix)]
|
||||
async fn get_fdflags(&mut self) -> Result<FdFlags, Error> {
|
||||
let fdflags = self.0.as_filelike().get_fd_flags()?;
|
||||
Ok(from_sysif_fdflags(fdflags))
|
||||
let fdflags = get_fd_flags(&self.0)?;
|
||||
Ok(fdflags)
|
||||
}
|
||||
async fn set_fdflags(&mut self, fdflags: FdFlags) -> Result<(), Error> {
|
||||
if fdflags == wasi_common::file::FdFlags::NONBLOCK {
|
||||
@@ -230,7 +228,7 @@ macro_rules! wasi_stream_write_impl {
|
||||
Ok(val)
|
||||
}
|
||||
async fn readable(&self) -> Result<(), Error> {
|
||||
let (readable, _writeable) = self.0.is_read_write()?;
|
||||
let (readable, _writeable) = is_read_write(&self.0)?;
|
||||
if readable {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -238,7 +236,7 @@ macro_rules! wasi_stream_write_impl {
|
||||
}
|
||||
}
|
||||
async fn writable(&self) -> Result<(), Error> {
|
||||
let (_readable, writeable) = self.0.is_read_write()?;
|
||||
let (_readable, writeable) = is_read_write(&self.0)?;
|
||||
if writeable {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -303,10 +301,50 @@ pub fn filetype_from(ft: &cap_std::fs::FileType) -> FileType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_sysif_fdflags(f: system_interface::fs::FdFlags) -> wasi_common::file::FdFlags {
|
||||
/// Return the file-descriptor flags for a given file-like object.
|
||||
///
|
||||
/// This returns the flags needed to implement [`WasiFile::get_fdflags`].
|
||||
pub fn get_fd_flags<Socketlike: AsSocketlike>(
|
||||
f: Socketlike,
|
||||
) -> io::Result<wasi_common::file::FdFlags> {
|
||||
// On Unix-family platforms, we can use the same system call that we'd use
|
||||
// for files on sockets here.
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
let mut out = wasi_common::file::FdFlags::empty();
|
||||
if f.contains(system_interface::fs::FdFlags::NONBLOCK) {
|
||||
if f.get_fd_flags()?
|
||||
.contains(system_interface::fs::FdFlags::NONBLOCK)
|
||||
{
|
||||
out |= wasi_common::file::FdFlags::NONBLOCK;
|
||||
}
|
||||
out
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
// On Windows, sockets are different, and there is no direct way to
|
||||
// query for the non-blocking flag. We can get a sufficient approximation
|
||||
// by testing whether a zero-length `recv` appears to block.
|
||||
#[cfg(windows)]
|
||||
match rustix::net::recv(f, &mut [], rustix::net::RecvFlags::empty()) {
|
||||
Ok(_) => Ok(wasi_common::file::FdFlags::empty()),
|
||||
Err(rustix::io::Errno::WOULDBLOCK) => Ok(wasi_common::file::FdFlags::NONBLOCK),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the file-descriptor flags for a given file-like object.
|
||||
///
|
||||
/// This returns the flags needed to implement [`WasiFile::get_fdflags`].
|
||||
pub fn is_read_write<Socketlike: AsSocketlike>(f: Socketlike) -> io::Result<(bool, bool)> {
|
||||
// On Unix-family platforms, we have an `IsReadWrite` impl.
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
f.is_read_write()
|
||||
}
|
||||
|
||||
// On Windows, we only have a `TcpStream` impl, so make a view first.
|
||||
#[cfg(windows)]
|
||||
{
|
||||
f.as_socketlike_view::<std::net::TcpStream>()
|
||||
.is_read_write()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user