Skip to content

Reenable cap-async-std. #370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ exclude = ["/.*"]
rust-version = "1.63"

[dev-dependencies]
#async-std = { version = "1.10.0", features = ["attributes"] }
async-std = { version = "1.13.0", features = ["attributes", "io_safety"] }
anyhow = "1.0.37"
#cap-async-std = { path = "cap-async-std", version = "^0.25.0" }
cap-fs-ext = { path = "cap-fs-ext", version = "^3.3.0" }
cap-net-ext = { path = "cap-net-ext", version = "^3.3.0" }
cap-directories = { path = "cap-directories", version = "^3.3.0" }
cap-std = { path = "cap-std", version = "^3.3.0" }
cap-tempfile = { path = "cap-tempfile", version = "^3.3.0" }
cap-rand = { path = "cap-rand", version = "^3.3.0" }
cap-async-std = { path = "cap-async-std", version = "3.3.0" }
cap-fs-ext = { path = "cap-fs-ext", version = "3.3.0" }
cap-net-ext = { path = "cap-net-ext", version = "3.3.0" }
cap-directories = { path = "cap-directories", version = "3.3.0" }
cap-std = { path = "cap-std", version = "3.3.0" }
cap-tempfile = { path = "cap-tempfile", version = "3.3.0" }
cap-rand = { path = "cap-rand", version = "3.3.0" }
rand = "0.8.1"
tempfile = "3.1.0"
camino = "1.0.5"
Expand Down Expand Up @@ -55,23 +55,23 @@ fs_utf8 = [
"cap-fs-ext/fs_utf8",
"cap-tempfile/fs_utf8",
]
#async_std_fs_utf8 = [
# "cap-async-std/fs_utf8",
# "cap-fs-ext/async_std_fs_utf8"
#]
async_std_fs_utf8 = [
"cap-async-std/fs_utf8",
"cap-fs-ext/async_std_fs_utf8"
]
arf_strings = [
"cap-std/arf_strings",
"cap-fs-ext/arf_strings",
"cap-tempfile/arf_strings",
]
#async_std_arf_strings = [
# "cap-async-std/arf_strings",
# "cap-fs-ext/async_std_arf_strings"
#]
async_std_arf_strings = [
"cap-async-std/arf_strings",
"cap-fs-ext/async_std_arf_strings"
]

[workspace]
members = [
#"cap-async-std",
"cap-async-std",
"cap-fs-ext",
"cap-net-ext",
"cap-directories",
Expand Down
10 changes: 4 additions & 6 deletions cap-async-std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cap-async-std"
version = "0.25.2"
version = "3.3.0"
description = "Capability-based version of async-std"
authors = [
"Dan Gohman <dev@sunfishcode.online>",
Expand All @@ -11,15 +11,13 @@ keywords = ["network", "file", "async", "future", "await"]
categories = ["filesystem", "network-programming", "asynchronous", "concurrency"]
repository = "https://github.com/bytecodealliance/cap-std"
edition = "2021"
publish = false # temporary, until async-rs/async-std#1036 is available

[dependencies]
arf-strings = { version = "0.7.0", optional = true }
# Enable "unstable" for `spawn_blocking`.
async-std = { version = "1.10.0", features = ["attributes", "unstable"] }
cap-primitives = { path = "../cap-primitives", version = "^0.25.0" }
async-std = { version = "1.13.0", features = ["attributes", "io_safety"] }
cap-primitives = { path = "../cap-primitives", version = "^3.3.0" }
io-lifetimes = { version = "2.0.0", default-features = false, features = ["async-std"] }
io-extras = { version = "0.17.0", features = ["use_async_std"] }
io-extras = { version = "0.18.3", features = ["use_async_std"] }
camino = { version = "1.0.5", optional = true }

[target.'cfg(not(windows))'.dependencies]
Expand Down
84 changes: 84 additions & 0 deletions cap-async-std/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::env::var;
use std::io::Write;

fn main() {
use_feature_or_nothing("windows_file_type_ext");

// Cfgs that users may set.
println!("cargo:rustc-check-cfg=cfg(io_lifetimes_use_std)");

// Don't rerun this on changes other than build.rs, as we only depend on
// the rustc version.
println!("cargo:rerun-if-changed=build.rs");
}

fn use_feature_or_nothing(feature: &str) {
if has_feature(feature) {
use_feature(feature);
}
println!("cargo:rustc-check-cfg=cfg({})", feature);
}

fn use_feature(feature: &str) {
println!("cargo:rustc-cfg={}", feature);
}

/// Test whether the rustc at `var("RUSTC")` supports the given feature.
fn has_feature(feature: &str) -> bool {
can_compile(&format!(
"#![allow(stable_features)]\n#![feature({})]",
feature
))
}

/// Test whether the rustc at `var("RUSTC")` can compile the given code.
fn can_compile<T: AsRef<str>>(test: T) -> bool {
use std::process::Stdio;

let out_dir = var("OUT_DIR").unwrap();
let rustc = var("RUSTC").unwrap();
let target = var("TARGET").unwrap();

// Use `RUSTC_WRAPPER` if it's set, unless it's set to an empty string,
// as documented [here].
// [here]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-reads
let wrapper = var("RUSTC_WRAPPER")
.ok()
.and_then(|w| if w.is_empty() { None } else { Some(w) });

let mut cmd = if let Some(wrapper) = wrapper {
let mut cmd = std::process::Command::new(wrapper);
// The wrapper's first argument is supposed to be the path to rustc.
cmd.arg(rustc);
cmd
} else {
std::process::Command::new(rustc)
};

cmd.arg("--crate-type=rlib") // Don't require `main`.
.arg("--emit=metadata") // Do as little as possible but still parse.
.arg("--target")
.arg(target)
.arg("--out-dir")
.arg(out_dir); // Put the output somewhere inconsequential.

// If Cargo wants to set RUSTFLAGS, use that.
if let Ok(rustflags) = var("CARGO_ENCODED_RUSTFLAGS") {
if !rustflags.is_empty() {
for arg in rustflags.split('\x1f') {
cmd.arg(arg);
}
}
}

let mut child = cmd
.arg("-") // Read from stdin.
.stdin(Stdio::piped()) // Stdin is a pipe.
.stderr(Stdio::null()) // Errors from feature detection aren't interesting and can be confusing.
.spawn()
.unwrap();

writeln!(child.stdin.take().unwrap(), "{}", test.as_ref()).unwrap();

child.wait().unwrap().success()
}
23 changes: 15 additions & 8 deletions cap-async-std/src/fs/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ use cap_primitives::fs::{
remove_open_dir_all, rename, set_permissions, stat, DirOptions, FollowSymlinks, Permissions,
};
use cap_primitives::AmbientAuthority;
use io_lifetimes::raw::{AsRawFilelike, FromRawFilelike};
#[cfg(not(windows))]
use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
use io_lifetimes::{AsFilelike, FromFilelike};
#[cfg(windows)]
use io_lifetimes::{AsHandle, BorrowedHandle, OwnedHandle};
use std::fmt;
use std::mem::ManuallyDrop;
#[cfg(unix)]
use {
crate::os::unix::net::{UnixDatagram, UnixListener, UnixStream},
Expand Down Expand Up @@ -883,15 +885,20 @@ impl Dir {
/// This can be useful when interacting with other libraries and or C/C++
/// code which has invoked `openat(..., O_DIRECTORY)` external to this
/// crate.
pub fn reopen_dir<Filelike: AsFilelike>(dir: &Filelike) -> io::Result<Self> {
spawn_blocking(move || {
cap_primitives::fs::open_dir(
&dir.as_filelike_view::<std::fs::File>(),
std::path::Component::CurDir.as_ref(),
)
pub async fn reopen_dir<Filelike: AsFilelike + Send>(dir: &Filelike) -> io::Result<Self> {
// Our public API has a `&Filelike` here, which prevents us from doing
// a `clone` as we usually do. So instead, we use the raw filelike, which
// we can clone and depend on it remaining open until we return.
let raw_filelike = dir.as_filelike_view::<std::fs::File>().as_raw_filelike();
// SAFETY: `raw_filelike` remains open for the duration of the
// `reopen_dir` call.
let file = ManuallyDrop::new(unsafe { std::fs::File::from_raw_filelike(raw_filelike) });
let dir = spawn_blocking(move || {
cap_primitives::fs::open_dir(&*file, std::path::Component::CurDir.as_ref())
})
.await
.map(Self::from_std_file)
.await?
.into();
Ok(Self::from_std_file(dir))
}
}

Expand Down
3 changes: 1 addition & 2 deletions cap-async-std/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ impl File {
#[inline]
pub async fn metadata(&self) -> io::Result<Metadata> {
let clone = self.clone();
let sync = clone.std.as_filelike_view::<std::fs::File>();
spawn_blocking(move || metadata_from(&*sync)).await
spawn_blocking(move || metadata_from(&*clone.std.as_filelike_view::<std::fs::File>())).await
}

// async_std doesn't have `try_clone`.
Expand Down
2 changes: 1 addition & 1 deletion cap-async-std/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ pub use cap_primitives::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permis
// Re-export conditional types from `cap_primitives`.
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
pub use cap_primitives::fs::FileTypeExt;
pub use cap_primitives::fs::{FileExt, OpenOptionsExt, MetadataExt};
#[cfg(unix)]
pub use cap_primitives::fs::{DirBuilderExt, PermissionsExt};
pub use cap_primitives::fs::{FileExt, MetadataExt, OpenOptionsExt};

// Re-export things from `async_std` that we can use as-is.
#[cfg(target_os = "wasi")]
Expand Down
48 changes: 26 additions & 22 deletions cap-async-std/src/fs_utf8/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use crate::fs_utf8::{from_utf8, to_utf8, DirBuilder, File, Metadata, ReadDir};
use async_std::{fs, io};
use camino::{Utf8Path, Utf8PathBuf};
use cap_primitives::AmbientAuthority;
use io_lifetimes::raw::{AsRawFilelike, FromRawFilelike};
use io_lifetimes::AsFilelike;
#[cfg(not(windows))]
use io_lifetimes::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd};
use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
#[cfg(windows)]
use io_lifetimes::{AsHandle, BorrowedHandle, OwnedHandle};
use std::fmt;
use std::mem::ManuallyDrop;
#[cfg(unix)]
use {
crate::os::unix::net::{UnixDatagram, UnixListener, UnixStream},
Expand Down Expand Up @@ -170,8 +172,8 @@ impl Dir {
to_dir: &Self,
to: Q,
) -> io::Result<u64> {
let from = from_utf8(from)?;
let to = from_utf8(to)?;
let from = from_utf8(from.as_ref())?;
let to = from_utf8(to.as_ref())?;
self.cap_std.copy(from, &to_dir.cap_std, to).await
}

Expand All @@ -186,8 +188,8 @@ impl Dir {
dst_dir: &Self,
dst: Q,
) -> io::Result<()> {
let src = from_utf8(src)?;
let dst = from_utf8(dst)?;
let src = from_utf8(src.as_ref())?;
let dst = from_utf8(dst.as_ref())?;
self.cap_std.hard_link(src, &dst_dir.cap_std, dst).await
}

Expand Down Expand Up @@ -321,8 +323,8 @@ impl Dir {
to_dir: &Self,
to: Q,
) -> io::Result<()> {
let from = from_utf8(from)?;
let to = from_utf8(to)?;
let from = from_utf8(from.as_ref())?;
let to = from_utf8(to.as_ref())?;
self.cap_std.rename(from, &to_dir.cap_std, to).await
}

Expand Down Expand Up @@ -388,8 +390,8 @@ impl Dir {
original: P,
link: Q,
) -> io::Result<()> {
let original = from_utf8(original)?;
let link = from_utf8(link)?;
let original = from_utf8(original.as_ref())?;
let link = from_utf8(link.as_ref())?;
self.cap_std.symlink(original, link).await
}

Expand All @@ -416,8 +418,8 @@ impl Dir {
original: P,
link: Q,
) -> io::Result<()> {
let original = from_utf8(original)?;
let link = from_utf8(link)?;
let original = from_utf8(original.as_ref())?;
let link = from_utf8(link.as_ref())?;
self.cap_std.symlink_file(original, link).await
}

Expand All @@ -444,8 +446,8 @@ impl Dir {
original: P,
link: Q,
) -> io::Result<()> {
let original = from_utf8(original)?;
let link = from_utf8(link)?;
let original = from_utf8(original.as_ref())?;
let link = from_utf8(link.as_ref())?;
self.cap_std.symlink_dir(original, link).await
}

Expand Down Expand Up @@ -655,15 +657,17 @@ impl Dir {
/// This can be useful when interacting with other libraries and or C/C++
/// code which has invoked `openat(..., O_DIRECTORY)` external to this
/// crate.
pub fn reopen_dir<Filelike: AsFilelike>(dir: &Filelike) -> io::Result<Self> {
spawn_blocking(move || {
cap_primitives::fs::open_dir(
&dir.as_filelike_view::<std::fs::File>(),
std::path::Component::CurDir.as_ref(),
)
})
.await
.map(Self::from_std_file)
pub async fn reopen_dir<Filelike: AsFilelike>(dir: &Filelike) -> io::Result<Self> {
// Our public API has a `&Filelike` here, which prevents us from doing
// a `clone` as we usually do. So instead, we use the raw fd, which we
// can clone and depend on it remaining open until we return.
let raw_filelike = dir.as_filelike_view::<std::fs::File>().as_raw_filelike();
// SAFETY: `raw_filelike` remains open for the duration of the `reopen_dir`
// call.
let file = ManuallyDrop::new(unsafe { std::fs::File::from_raw_filelike(raw_filelike) });
crate::fs::Dir::reopen_dir(&*file)
.await
.map(Self::from_cap_std)
}
}

Expand Down
13 changes: 6 additions & 7 deletions cap-async-std/src/fs_utf8/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use async_std::task::{Context, Poll};
use camino::Utf8Path;
use cap_primitives::AmbientAuthority;
#[cfg(not(windows))]
use io_lifetimes::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd};
use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
#[cfg(windows)]
use io_lifetimes::{AsHandle, BorrowedHandle, OwnedHandle};
use std::fmt;
Expand Down Expand Up @@ -93,8 +93,7 @@ impl File {
/// This corresponds to [`async_std::fs::File::metadata`].
#[inline]
pub async fn metadata(&self) -> io::Result<Metadata> {
let clone = self.clone();
spawn_blocking(move || clone.metadata()).await
self.cap_std.metadata().await
}

// async_std doesn't have `try_clone`.
Expand All @@ -119,7 +118,7 @@ impl File {
path: P,
ambient_authority: AmbientAuthority,
) -> io::Result<Self> {
let path = from_utf8(path)?;
let path = from_utf8(path.as_ref())?;
crate::fs::File::open_ambient(path, ambient_authority)
.await
.map(Self::from_cap_std)
Expand All @@ -134,11 +133,11 @@ impl File {
/// This function is not sandboxed and may access any path that the host
/// process has access to.
#[inline]
pub async fn create_ambient<P: AsRef<Path>>(
pub async fn create_ambient<P: AsRef<Utf8Path>>(
path: P,
ambient_authority: AmbientAuthority,
) -> io::Result<Self> {
let path = from_utf8(path)?;
let path = from_utf8(path.as_ref())?;
crate::fs::File::create_ambient(path, ambient_authority)
.await
.map(Self::from_cap_std)
Expand All @@ -158,7 +157,7 @@ impl File {
options: &OpenOptions,
ambient_authority: AmbientAuthority,
) -> io::Result<Self> {
let path = from_utf8(path)?;
let path = from_utf8(path.as_ref())?;
crate::fs::File::open_ambient_with(path, options, ambient_authority)
.await
.map(Self::from_cap_std)
Expand Down
Loading
Loading