diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 22959050..b4f7f62f 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -150,6 +150,7 @@ jobs:
riscv64gc-unknown-linux-gnu
arm-unknown-linux-gnueabihf
aarch64-linux-android
+ wasm32-wasi
- run: cargo check --workspace --all-targets --all-features --release -vv
- run: cargo check --workspace --all-targets --all-features --release -vv --target=x86_64-unknown-linux-musl
- run: cargo check --workspace --all-targets --all-features --release -vv --target=x86_64-unknown-linux-gnux32
@@ -163,6 +164,7 @@ jobs:
- run: cargo check --workspace --all-targets --all-features --release -vv --target=riscv64gc-unknown-linux-gnu
- run: cargo check --workspace --all-targets --all-features --release -vv --target=arm-unknown-linux-gnueabihf
- run: cargo check --workspace --all-targets --all-features --release -vv --target=aarch64-linux-android
+ - run: cd cap-std && cargo check --features=fs_utf8 --release -vv
check_cross_nightly_windows:
name: Check Cross-Compilation on Rust nightly on Windows
diff --git a/cap-primitives/src/fs/dir_options.rs b/cap-primitives/src/fs/dir_options.rs
index d9c6a7f8..358492eb 100644
--- a/cap-primitives/src/fs/dir_options.rs
+++ b/cap-primitives/src/fs/dir_options.rs
@@ -1,3 +1,4 @@
+#[cfg(not(target_os = "wasi"))]
use crate::fs::DirOptionsExt;
/// Options and flags which can be used to configure how a directory is
@@ -6,6 +7,7 @@ use crate::fs::DirOptionsExt;
/// This is to `create_dir` what to `OpenOptions` is to `open`.
#[derive(Debug, Clone)]
pub struct DirOptions {
+ #[cfg(not(target_os = "wasi"))]
#[allow(dead_code)]
pub(crate) ext: DirOptionsExt,
}
@@ -16,6 +18,7 @@ impl DirOptions {
#[inline]
pub const fn new() -> Self {
Self {
+ #[cfg(not(target_os = "wasi"))]
ext: DirOptionsExt::new(),
}
}
diff --git a/cap-primitives/src/fs/metadata.rs b/cap-primitives/src/fs/metadata.rs
index 3302a90e..58aad8f3 100644
--- a/cap-primitives/src/fs/metadata.rs
+++ b/cap-primitives/src/fs/metadata.rs
@@ -259,6 +259,44 @@ impl std::os::unix::fs::MetadataExt for Metadata {
}
}
+#[cfg(target_os = "wasi")]
+impl std::os::wasi::fs::MetadataExt for Metadata {
+ #[inline]
+ fn dev(&self) -> u64 {
+ self.ext.dev()
+ }
+
+ #[inline]
+ fn ino(&self) -> u64 {
+ self.ext.ino()
+ }
+
+ #[inline]
+ fn nlink(&self) -> u64 {
+ self.ext.nlink()
+ }
+
+ #[inline]
+ fn size(&self) -> u64 {
+ self.ext.size()
+ }
+
+ #[inline]
+ fn atim(&self) -> u64 {
+ self.ext.atim()
+ }
+
+ #[inline]
+ fn mtim(&self) -> u64 {
+ self.ext.mtim()
+ }
+
+ #[inline]
+ fn ctim(&self) -> u64 {
+ self.ext.ctim()
+ }
+}
+
#[cfg(target_os = "vxworks")]
impl std::os::vxworks::fs::MetadataExt for Metadata {
#[inline]
diff --git a/cap-primitives/src/fs/mod.rs b/cap-primitives/src/fs/mod.rs
index 9172d855..70853687 100644
--- a/cap-primitives/src/fs/mod.rs
+++ b/cap-primitives/src/fs/mod.rs
@@ -32,6 +32,7 @@ mod remove_file;
mod remove_open_dir;
mod rename;
mod reopen;
+#[cfg(not(target_os = "wasi"))]
mod set_permissions;
mod set_times;
mod stat;
@@ -85,6 +86,7 @@ pub use remove_file::remove_file;
pub use remove_open_dir::{remove_open_dir, remove_open_dir_all};
pub use rename::rename;
pub use reopen::reopen;
+#[cfg(not(target_os = "wasi"))]
pub use set_permissions::set_permissions;
pub use set_times::{set_times, set_times_nofollow};
pub use stat::stat;
diff --git a/cap-primitives/src/fs/open_options.rs b/cap-primitives/src/fs/open_options.rs
index 8b3b55be..de634785 100644
--- a/cap-primitives/src/fs/open_options.rs
+++ b/cap-primitives/src/fs/open_options.rs
@@ -178,6 +178,41 @@ impl std::os::unix::fs::OpenOptionsExt for OpenOptions {
}
}
+#[cfg(target_os = "wasi")]
+impl std::os::wasi::fs::OpenOptionsExt for OpenOptions {
+ fn lookup_flags(&mut self, _: u32) -> &mut Self {
+ todo!()
+ }
+ fn directory(&mut self, dir_required: bool) -> &mut Self {
+ self.dir_required = dir_required;
+ self
+ }
+ fn dsync(&mut self, _: bool) -> &mut Self {
+ todo!()
+ }
+ fn nonblock(&mut self, _: bool) -> &mut Self {
+ todo!()
+ }
+ fn rsync(&mut self, _: bool) -> &mut Self {
+ todo!()
+ }
+ fn sync(&mut self, _: bool) -> &mut Self {
+ todo!()
+ }
+ fn fs_rights_base(&mut self, _: u64) -> &mut Self {
+ todo!()
+ }
+ fn fs_rights_inheriting(&mut self, _: u64) -> &mut Self {
+ todo!()
+ }
+ fn open_at
(&self, dirfd: &std::fs::File, path: P) -> Result
+ where
+ P: AsRef,
+ {
+ crate::fs::open(dirfd, path.as_ref(), self)
+ }
+}
+
#[cfg(target_os = "vxworks")]
impl std::os::vxworks::fs::OpenOptionsExt for OpenOptions {
#[inline]
diff --git a/cap-primitives/src/fs/permissions.rs b/cap-primitives/src/fs/permissions.rs
index 9d9f9ac1..be356b68 100644
--- a/cap-primitives/src/fs/permissions.rs
+++ b/cap-primitives/src/fs/permissions.rs
@@ -1,4 +1,4 @@
-#[cfg(any(unix, target_os = "vxworks"))]
+#[cfg(not(windows))]
use crate::fs::PermissionsExt;
#[cfg(unix)]
use rustix::fs::RawMode;
@@ -52,6 +52,15 @@ impl Permissions {
Ok(fs::Permissions::from_mode(self.ext.mode()))
}
+ #[cfg(target_os = "wasi")]
+ #[inline]
+ #[allow(clippy::unnecessary_wraps)]
+ fn _into_std(self, file: &fs::File) -> io::Result {
+ let mut permissions = file.metadata()?.permissions();
+ permissions.set_readonly(self.readonly());
+ Ok(permissions)
+ }
+
#[cfg(windows)]
#[inline]
fn _into_std(self, file: &fs::File) -> io::Result {
diff --git a/cap-primitives/src/rustix/fs/copy_impl.rs b/cap-primitives/src/rustix/fs/copy_impl.rs
index 312a7928..561a6ac7 100644
--- a/cap-primitives/src/rustix/fs/copy_impl.rs
+++ b/cap-primitives/src/rustix/fs/copy_impl.rs
@@ -25,6 +25,7 @@ fn open_from(start: &fs::File, path: &Path) -> io::Result<(fs::File, fs::Metadat
Ok((reader, metadata))
}
+#[cfg(not(target_os = "wasi"))]
fn open_to_and_set_permissions(
start: &fs::File,
path: &Path,
@@ -54,6 +55,25 @@ fn open_to_and_set_permissions(
Ok((writer, writer_metadata))
}
+#[cfg(target_os = "wasi")]
+fn open_to_and_set_permissions(
+ start: &fs::File,
+ path: &Path,
+ reader_metadata: fs::Metadata,
+) -> io::Result<(fs::File, fs::Metadata)> {
+ let writer = open(
+ start,
+ path,
+ OpenOptions::new()
+ // create the file with the correct mode right away
+ .write(true)
+ .create(true)
+ .truncate(true),
+ )?;
+ let writer_metadata = writer.metadata()?;
+ Ok((writer, writer_metadata))
+}
+
#[cfg(not(any(
target_os = "linux",
target_os = "android",
diff --git a/cap-primitives/src/rustix/fs/create_dir_unchecked.rs b/cap-primitives/src/rustix/fs/create_dir_unchecked.rs
index 38dbd11c..652162c7 100644
--- a/cap-primitives/src/rustix/fs/create_dir_unchecked.rs
+++ b/cap-primitives/src/rustix/fs/create_dir_unchecked.rs
@@ -10,9 +10,10 @@ pub(crate) fn create_dir_unchecked(
path: &Path,
options: &DirOptions,
) -> io::Result<()> {
- Ok(mkdirat(
- start,
- path,
- Mode::from_bits(options.ext.mode as RawMode).unwrap(),
- )?)
+ #[cfg(not(target_os = "wasi"))]
+ let raw_mode = options.ext.mode as RawMode;
+ #[cfg(target_os = "wasi")]
+ let raw_mode = 0;
+
+ Ok(mkdirat(start, path, Mode::from_bits(raw_mode).unwrap())?)
}
diff --git a/cap-primitives/src/rustix/fs/dir_utils.rs b/cap-primitives/src/rustix/fs/dir_utils.rs
index 85e04b47..bb18ee02 100644
--- a/cap-primitives/src/rustix/fs/dir_utils.rs
+++ b/cap-primitives/src/rustix/fs/dir_utils.rs
@@ -6,7 +6,7 @@ use std::ops::Deref;
#[cfg(unix)]
use std::os::unix::{ffi::OsStrExt, fs::OpenOptionsExt};
#[cfg(target_os = "wasi")]
-use std::os::wasi::{ffi::OsStrExt, fs::OpenOptionsExt};
+use std::os::wasi::ffi::OsStrExt;
use std::path::Path;
#[cfg(racy_asserts)]
use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::PathBuf};
@@ -104,10 +104,13 @@ pub(crate) fn open_ambient_dir_impl(path: &Path, _: AmbientAuthority) -> io::Res
// `O_DIRECTORY` manually.
let flags = OFlags::DIRECTORY | target_o_path();
- fs::OpenOptions::new()
- .read(true)
- .custom_flags(flags.bits() as i32)
- .open(&path)
+ let mut options = fs::OpenOptions::new();
+ options.read(true);
+
+ #[cfg(not(target_os = "wasi"))]
+ options.custom_flags(flags.bits() as i32);
+
+ options.open(&path)
}
/// Use `O_PATH` on platforms which have it, or none otherwise.
@@ -131,6 +134,7 @@ pub(crate) const fn target_o_path() -> OFlags {
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
+ target_os = "wasi",
))]
{
OFlags::empty()
diff --git a/cap-primitives/src/rustix/fs/file_path.rs b/cap-primitives/src/rustix/fs/file_path.rs
index 8e144878..211ec01b 100644
--- a/cap-primitives/src/rustix/fs/file_path.rs
+++ b/cap-primitives/src/rustix/fs/file_path.rs
@@ -6,8 +6,6 @@ use std::ffi::OsString;
use std::fs;
#[cfg(unix)]
use std::os::unix::ffi::OsStringExt;
-#[cfg(target_os = "wasi")]
-use std::os::wasi::ffi::OsStringExt;
use std::path::PathBuf;
pub(crate) fn file_path_by_ttyname_or_seaching(file: &fs::File) -> Option {
diff --git a/cap-primitives/src/rustix/fs/file_type_ext.rs b/cap-primitives/src/rustix/fs/file_type_ext.rs
index 868c3c46..64ca2a03 100644
--- a/cap-primitives/src/rustix/fs/file_type_ext.rs
+++ b/cap-primitives/src/rustix/fs/file_type_ext.rs
@@ -44,12 +44,16 @@ impl FileTypeExt {
FileType::ext(Self::BlockDevice)
} else if std.is_char_device() {
FileType::ext(Self::CharDevice)
- } else if std.is_fifo() {
- FileType::ext(Self::Fifo)
- } else if std.is_socket() {
- FileType::ext(Self::Socket)
} else {
- FileType::unknown()
+ #[cfg(not(target_os = "wasi"))]
+ if std.is_fifo() {
+ return FileType::ext(Self::Fifo);
+ }
+ if std.is_socket() {
+ FileType::ext(Self::Socket)
+ } else {
+ FileType::unknown()
+ }
}
}
diff --git a/cap-primitives/src/rustix/fs/metadata_ext.rs b/cap-primitives/src/rustix/fs/metadata_ext.rs
index 2eb04646..6087121a 100644
--- a/cap-primitives/src/rustix/fs/metadata_ext.rs
+++ b/cap-primitives/src/rustix/fs/metadata_ext.rs
@@ -1,6 +1,7 @@
#![allow(clippy::useless_conversion)]
-use crate::fs::{FileTypeExt, Metadata, PermissionsExt};
+use crate::fs::PermissionsExt;
+use crate::fs::{FileTypeExt, Metadata};
use crate::time::{Duration, SystemClock, SystemTime};
#[cfg(all(target_os = "linux", target_env = "gnu"))]
use rustix::fs::{makedev, Statx};
@@ -12,20 +13,38 @@ use std::{fs, io};
pub(crate) struct MetadataExt {
dev: u64,
ino: u64,
+ #[cfg(not(target_os = "wasi"))]
mode: u32,
nlink: u64,
+ #[cfg(not(target_os = "wasi"))]
uid: u32,
+ #[cfg(not(target_os = "wasi"))]
gid: u32,
+ #[cfg(not(target_os = "wasi"))]
rdev: u64,
size: u64,
+ #[cfg(not(target_os = "wasi"))]
atime: i64,
+ #[cfg(not(target_os = "wasi"))]
atime_nsec: i64,
+ #[cfg(not(target_os = "wasi"))]
mtime: i64,
+ #[cfg(not(target_os = "wasi"))]
mtime_nsec: i64,
+ #[cfg(not(target_os = "wasi"))]
ctime: i64,
+ #[cfg(not(target_os = "wasi"))]
ctime_nsec: i64,
+ #[cfg(not(target_os = "wasi"))]
blksize: u64,
+ #[cfg(not(target_os = "wasi"))]
blocks: u64,
+ #[cfg(target_os = "wasi")]
+ atim: u64,
+ #[cfg(target_os = "wasi")]
+ mtim: u64,
+ #[cfg(target_os = "wasi")]
+ ctim: u64,
}
impl MetadataExt {
@@ -46,20 +65,38 @@ impl MetadataExt {
Self {
dev: std.dev(),
ino: std.ino(),
+ #[cfg(not(target_os = "wasi"))]
mode: std.mode(),
nlink: std.nlink(),
+ #[cfg(not(target_os = "wasi"))]
uid: std.uid(),
+ #[cfg(not(target_os = "wasi"))]
gid: std.gid(),
+ #[cfg(not(target_os = "wasi"))]
rdev: std.rdev(),
size: std.size(),
+ #[cfg(not(target_os = "wasi"))]
atime: std.atime(),
+ #[cfg(not(target_os = "wasi"))]
atime_nsec: std.atime_nsec(),
+ #[cfg(not(target_os = "wasi"))]
mtime: std.mtime(),
+ #[cfg(not(target_os = "wasi"))]
mtime_nsec: std.mtime_nsec(),
+ #[cfg(not(target_os = "wasi"))]
ctime: std.ctime(),
+ #[cfg(not(target_os = "wasi"))]
ctime_nsec: std.ctime_nsec(),
+ #[cfg(not(target_os = "wasi"))]
blksize: std.blksize(),
+ #[cfg(not(target_os = "wasi"))]
blocks: std.blocks(),
+ #[cfg(target_os = "wasi")]
+ atim: std.atim(),
+ #[cfg(target_os = "wasi")]
+ mtim: std.mtim(),
+ #[cfg(target_os = "wasi")]
+ ctim: std.ctim(),
}
}
@@ -69,14 +106,17 @@ impl MetadataExt {
Metadata {
file_type: FileTypeExt::from_raw_mode(stat.st_mode as RawMode),
len: u64::try_from(stat.st_size).unwrap(),
+ #[cfg(not(target_os = "wasi"))]
permissions: PermissionsExt::from_raw_mode(stat.st_mode as RawMode),
+ #[cfg(target_os = "wasi")]
+ permissions: PermissionsExt::default(),
- #[cfg(not(target_os = "netbsd"))]
+ #[cfg(not(any(target_os = "netbsd", target_os = "wasi")))]
modified: system_time_from_rustix(
stat.st_mtime.try_into().unwrap(),
stat.st_mtime_nsec as _,
),
- #[cfg(not(target_os = "netbsd"))]
+ #[cfg(not(any(target_os = "netbsd", target_os = "wasi")))]
accessed: system_time_from_rustix(
stat.st_atime.try_into().unwrap(),
stat.st_atime_nsec as _,
@@ -93,6 +133,11 @@ impl MetadataExt {
stat.st_atimensec as _,
),
+ #[cfg(target_os = "wasi")]
+ modified: system_time_from_rustix(stat.st_mtim.tv_sec, stat.st_mtim.tv_nsec as _),
+ #[cfg(target_os = "wasi")]
+ accessed: system_time_from_rustix(stat.st_atim.tv_sec, stat.st_atim.tv_nsec as _),
+
#[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
@@ -123,29 +168,53 @@ impl MetadataExt {
ext: Self {
dev: u64::try_from(stat.st_dev).unwrap(),
ino: stat.st_ino.into(),
+ #[cfg(not(target_os = "wasi"))]
mode: u32::from(stat.st_mode),
nlink: u64::from(stat.st_nlink),
+ #[cfg(not(target_os = "wasi"))]
uid: stat.st_uid,
+ #[cfg(not(target_os = "wasi"))]
gid: stat.st_gid,
+ #[cfg(not(target_os = "wasi"))]
rdev: u64::try_from(stat.st_rdev).unwrap(),
size: u64::try_from(stat.st_size).unwrap(),
+ #[cfg(not(target_os = "wasi"))]
atime: i64::try_from(stat.st_atime).unwrap(),
- #[cfg(not(target_os = "netbsd"))]
+ #[cfg(not(any(target_os = "netbsd", target_os = "wasi")))]
atime_nsec: stat.st_atime_nsec as _,
#[cfg(target_os = "netbsd")]
atime_nsec: stat.st_atimensec as _,
+ #[cfg(not(target_os = "wasi"))]
mtime: i64::try_from(stat.st_mtime).unwrap(),
- #[cfg(not(target_os = "netbsd"))]
+ #[cfg(not(any(target_os = "netbsd", target_os = "wasi")))]
mtime_nsec: stat.st_mtime_nsec as _,
#[cfg(target_os = "netbsd")]
mtime_nsec: stat.st_mtimensec as _,
+ #[cfg(not(target_os = "wasi"))]
ctime: i64::try_from(stat.st_ctime).unwrap(),
- #[cfg(not(target_os = "netbsd"))]
+ #[cfg(not(any(target_os = "netbsd", target_os = "wasi")))]
ctime_nsec: stat.st_ctime_nsec as _,
#[cfg(target_os = "netbsd")]
ctime_nsec: stat.st_ctimensec as _,
+ #[cfg(not(target_os = "wasi"))]
blksize: u64::try_from(stat.st_blksize).unwrap(),
+ #[cfg(not(target_os = "wasi"))]
blocks: u64::try_from(stat.st_blocks).unwrap(),
+ #[cfg(target_os = "wasi")]
+ atim: u64::try_from(
+ stat.st_atim.tv_sec as u64 * 1000000000 + stat.st_atim.tv_nsec as u64,
+ )
+ .unwrap(),
+ #[cfg(target_os = "wasi")]
+ mtim: u64::try_from(
+ stat.st_mtim.tv_sec as u64 * 1000000000 + stat.st_mtim.tv_nsec as u64,
+ )
+ .unwrap(),
+ #[cfg(target_os = "wasi")]
+ ctim: u64::try_from(
+ stat.st_ctim.tv_sec as u64 * 1000000000 + stat.st_ctim.tv_nsec as u64,
+ )
+ .unwrap(),
},
}
}
@@ -207,6 +276,7 @@ impl rustix::fs::MetadataExt for MetadataExt {
self.ino
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn mode(&self) -> u32 {
self.mode
@@ -217,16 +287,19 @@ impl rustix::fs::MetadataExt for MetadataExt {
self.nlink
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn uid(&self) -> u32 {
self.uid
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn gid(&self) -> u32 {
self.gid
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn rdev(&self) -> u64 {
self.rdev
@@ -237,43 +310,66 @@ impl rustix::fs::MetadataExt for MetadataExt {
self.size
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn atime(&self) -> i64 {
self.atime
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn atime_nsec(&self) -> i64 {
self.atime_nsec
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn mtime(&self) -> i64 {
self.mtime
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn mtime_nsec(&self) -> i64 {
self.mtime_nsec
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn ctime(&self) -> i64 {
self.ctime
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn ctime_nsec(&self) -> i64 {
self.ctime_nsec
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn blksize(&self) -> u64 {
self.blksize
}
+ #[cfg(not(target_os = "wasi"))]
#[inline]
fn blocks(&self) -> u64 {
self.blocks
}
+
+ #[cfg(target_os = "wasi")]
+ fn atim(&self) -> u64 {
+ self.atim
+ }
+
+ #[cfg(target_os = "wasi")]
+ fn mtim(&self) -> u64 {
+ self.mtim
+ }
+
+ #[cfg(target_os = "wasi")]
+ fn ctim(&self) -> u64 {
+ self.ctim
+ }
}
diff --git a/cap-primitives/src/rustix/fs/mod.rs b/cap-primitives/src/rustix/fs/mod.rs
index 29e619a3..9dcd1e4a 100644
--- a/cap-primitives/src/rustix/fs/mod.rs
+++ b/cap-primitives/src/rustix/fs/mod.rs
@@ -1,6 +1,7 @@
mod copy_impl;
mod create_dir_unchecked;
mod dir_entry_inner;
+#[cfg(not(target_os = "wasi"))]
mod dir_options_ext;
mod dir_utils;
#[cfg(not(any(target_os = "android", target_os = "linux")))]
@@ -23,7 +24,7 @@ mod remove_file_unchecked;
mod remove_open_dir_by_searching;
mod rename_unchecked;
mod reopen_impl;
-#[cfg(not(any(target_os = "android", target_os = "linux")))]
+#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))]
mod set_permissions_impl;
#[cfg(not(any(target_os = "android", target_os = "linux")))]
mod set_times_impl;
@@ -62,8 +63,10 @@ pub(super) use file_path::file_path_by_ttyname_or_seaching;
target_os = "ios"
)))]
pub(crate) use file_path::file_path_by_ttyname_or_seaching as file_path;
+#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))]
+pub(crate) use set_permissions_impl::set_permissions_impl;
#[cfg(not(any(target_os = "android", target_os = "linux")))]
-pub(crate) use {set_permissions_impl::set_permissions_impl, set_times_impl::set_times_impl};
+pub(crate) use set_times_impl::set_times_impl;
#[rustfmt::skip]
pub(crate) use crate::fs::{
@@ -80,6 +83,7 @@ pub(crate) use crate::fs::{
pub(crate) use copy_impl::copy_impl;
pub(crate) use create_dir_unchecked::create_dir_unchecked;
pub(crate) use dir_entry_inner::DirEntryInner;
+#[cfg(not(target_os = "wasi"))]
pub(crate) use dir_options_ext::DirOptionsExt;
pub(crate) use dir_utils::*;
pub(crate) use file_type_ext::FileTypeExt;
diff --git a/cap-primitives/src/rustix/fs/oflags.rs b/cap-primitives/src/rustix/fs/oflags.rs
index a4259473..85ffbd2a 100644
--- a/cap-primitives/src/rustix/fs/oflags.rs
+++ b/cap-primitives/src/rustix/fs/oflags.rs
@@ -21,8 +21,11 @@ pub(in super::super) fn compute_oflags(options: &OpenOptions) -> io::Result {
diff --git a/cap-primitives/src/rustix/fs/permissions_ext.rs b/cap-primitives/src/rustix/fs/permissions_ext.rs
index e0855ab9..ffbec959 100644
--- a/cap-primitives/src/rustix/fs/permissions_ext.rs
+++ b/cap-primitives/src/rustix/fs/permissions_ext.rs
@@ -4,9 +4,11 @@ use std::fs;
#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) struct PermissionsExt {
+ #[cfg(not(target_os = "wasi"))]
mode: RawMode,
}
+#[cfg(not(target_os = "wasi"))]
impl PermissionsExt {
/// Constructs a new instance of `Self` from the given
/// [`std::fs::Permissions`].
@@ -49,6 +51,7 @@ impl PermissionsExt {
}
}
+#[cfg(not(target_os = "wasi"))]
impl std::os::unix::fs::PermissionsExt for PermissionsExt {
fn mode(&self) -> u32 {
self.mode as u32
@@ -64,3 +67,10 @@ impl std::os::unix::fs::PermissionsExt for PermissionsExt {
}
}
}
+
+#[cfg(target_os = "wasi")]
+impl PermissionsExt {
+ pub(crate) fn default() -> Permissions {
+ Permissions { readonly: false }
+ }
+}
diff --git a/cap-std/src/fs/dir.rs b/cap-std/src/fs/dir.rs
index 6e3e245c..e02a4d48 100644
--- a/cap-std/src/fs/dir.rs
+++ b/cap-std/src/fs/dir.rs
@@ -1,10 +1,12 @@
use crate::fs::{DirBuilder, File, Metadata, OpenOptions, ReadDir};
#[cfg(unix)]
use crate::os::unix::net::{UnixDatagram, UnixListener, UnixStream};
+#[cfg(not(target_os = "wasi"))]
+use cap_primitives::fs::set_permissions;
use cap_primitives::fs::{
canonicalize, copy, create_dir, hard_link, open, open_ambient_dir, open_dir, open_parent_dir,
read_base_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, remove_open_dir,
- remove_open_dir_all, rename, set_permissions, stat, DirOptions, FollowSymlinks, Permissions,
+ remove_open_dir_all, rename, stat, DirOptions, FollowSymlinks, Permissions,
};
use cap_primitives::AmbientAuthority;
#[cfg(not(windows))]
@@ -125,6 +127,7 @@ impl Dir {
/// builder.
///
/// This corresponds to [`std::fs::DirBuilder::create`].
+ #[cfg(not(target_os = "wasi"))]
#[inline]
pub fn create_dir_with>(
&self,
@@ -234,7 +237,7 @@ impl Dir {
/// This corresponds to [`std::fs::metadata`], but only accesses paths
/// relative to `self`.
#[inline]
- pub fn metadata>(&self, path: P) -> io::Result {
+ pub fn metadata>(&self, path: P) -> io::Result {
stat(&self.std_file, path.as_ref(), FollowSymlinks::Yes)
}
@@ -364,6 +367,7 @@ impl Dir {
/// paths relative to `self`. Also, on some platforms, this function
/// may fail if the file or directory cannot be opened for reading or
/// writing first.
+ #[cfg(not(target_os = "wasi"))]
#[inline]
pub fn set_permissions>(&self, path: P, perm: Permissions) -> io::Result<()> {
set_permissions(&self.std_file, path.as_ref(), perm)
diff --git a/cap-std/src/fs/file.rs b/cap-std/src/fs/file.rs
index 9e22e33f..9240b2ad 100644
--- a/cap-std/src/fs/file.rs
+++ b/cap-std/src/fs/file.rs
@@ -8,8 +8,6 @@ use io_lifetimes::{AsFd, BorrowedFd, FromFd, IntoFd, OwnedFd};
#[cfg(windows)]
use io_lifetimes::{AsHandle, BorrowedHandle, FromHandle, IntoHandle, OwnedHandle};
use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
-#[cfg(target_os = "wasi")]
-use std::path::Path;
use std::path::Path;
use std::{fmt, fs, process};
#[cfg(windows)]
@@ -150,30 +148,16 @@ impl File {
}
}
-#[cfg(not(target_os = "wasi"))]
#[inline]
fn metadata_from(file: &fs::File) -> io::Result {
Metadata::from_file(file)
}
-#[cfg(target_os = "wasi")]
-#[inline]
-fn metadata_from(file: &fs::File) -> io::Result {
- file.metadata()
-}
-
-#[cfg(not(target_os = "wasi"))]
#[inline]
fn permissions_into_std(file: &fs::File, permissions: Permissions) -> io::Result {
permissions.into_std(file)
}
-#[cfg(target_os = "wasi")]
-#[inline]
-fn permissions_into_std(_file: &fs::File, permissions: Permissions) -> io::Result {
- permissions
-}
-
#[cfg(not(windows))]
impl FromRawFd for File {
#[inline]
@@ -479,15 +463,25 @@ impl std::os::unix::fs::FileExt for File {
#[cfg(target_os = "wasi")]
impl std::os::wasi::fs::FileExt for File {
#[inline]
- fn read_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result {
+ fn read_at(&self, bufs: &mut [u8], offset: u64) -> io::Result {
self.std.read_at(bufs, offset)
}
#[inline]
- fn write_at(&self, bufs: &[IoSlice], offset: u64) -> io::Result {
+ fn write_at(&self, bufs: &[u8], offset: u64) -> io::Result {
self.std.write_at(bufs, offset)
}
+ #[inline]
+ fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result {
+ self.std.read_vectored_at(bufs, offset)
+ }
+
+ #[inline]
+ fn write_vectored_at(&self, bufs: &[IoSlice], offset: u64) -> io::Result {
+ self.std.write_vectored_at(bufs, offset)
+ }
+
#[inline]
fn tell(&self) -> std::result::Result {
self.std.tell()
diff --git a/cap-std/src/fs/mod.rs b/cap-std/src/fs/mod.rs
index 29ff968e..e3ec3855 100644
--- a/cap-std/src/fs/mod.rs
+++ b/cap-std/src/fs/mod.rs
@@ -32,10 +32,5 @@ pub use dir_entry::DirEntry;
pub use file::File;
pub use read_dir::ReadDir;
-// Re-export things from `cap_primitives` that we can use as-is.
-#[cfg(not(target_os = "wasi"))]
+// Re-export types from `cap_primitives`.
pub use cap_primitives::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
-
-// Re-export things from `std` that we can use as-is.
-#[cfg(target_os = "wasi")]
-pub use std::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
diff --git a/cap-std/src/fs_utf8/dir.rs b/cap-std/src/fs_utf8/dir.rs
index dc491fe7..b696a5e2 100644
--- a/cap-std/src/fs_utf8/dir.rs
+++ b/cap-std/src/fs_utf8/dir.rs
@@ -110,6 +110,7 @@ impl Dir {
/// builder.
///
/// This corresponds to [`std::fs::DirBuilder::create`].
+ #[cfg(not(target_os = "wasi"))]
#[inline]
pub fn create_dir_with>(
&self,
@@ -308,6 +309,7 @@ impl Dir {
/// paths relative to `self`. Also, on some platforms, this function
/// may fail if the file or directory cannot be opened for reading or
/// writing first.
+ #[cfg(not(target_os = "wasi"))]
pub fn set_permissions>(
&self,
path: P,
diff --git a/cap-std/src/fs_utf8/file.rs b/cap-std/src/fs_utf8/file.rs
index 9315188a..a597dbad 100644
--- a/cap-std/src/fs_utf8/file.rs
+++ b/cap-std/src/fs_utf8/file.rs
@@ -462,13 +462,23 @@ impl std::os::unix::fs::FileExt for File {
#[cfg(target_os = "wasi")]
impl std::os::wasi::fs::FileExt for File {
#[inline]
- fn read_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result {
- self.cap_std.read_at(bufs, offset)
+ fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result {
+ self.cap_std.read_at(buf, offset)
+ }
+
+ #[inline]
+ fn write_at(&self, buf: &[u8], offset: u64) -> io::Result {
+ self.cap_std.write_at(buf, offset)
+ }
+
+ #[inline]
+ fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result {
+ self.cap_std.read_vectored_at(bufs, offset)
}
#[inline]
- fn write_at(&self, bufs: &[IoSlice], offset: u64) -> io::Result {
- self.cap_std.write_at(bufs, offset)
+ fn write_vectored_at(&self, bufs: &[IoSlice], offset: u64) -> io::Result {
+ self.cap_std.write_vectored_at(bufs, offset)
}
#[inline]
@@ -501,45 +511,39 @@ impl std::os::wasi::fs::FileExt for File {
}
#[inline]
- fn create_directory>(
- &self,
- dir: P,
- ) -> std::result::Result<(), std::io::Error> {
- let path = from_utf8(path)?;
- self.cap_std.create_directory(dir)
+ fn create_directory>(&self, path: P) -> std::result::Result<(), std::io::Error> {
+ let path = path.as_ref();
+ self.cap_std.create_directory(path)
}
#[inline]
- fn read_link>(
+ fn read_link>(
&self,
path: P,
) -> std::result::Result {
- let path = from_utf8(path)?;
+ let path = path.as_ref();
self.cap_std.read_link(path)
}
#[inline]
- fn metadata_at>(
+ fn metadata_at>(
&self,
lookup_flags: u32,
path: P,
) -> std::result::Result {
- let path = from_utf8(path)?;
+ let path = path.as_ref();
self.cap_std.metadata_at(lookup_flags, path)
}
#[inline]
- fn remove_file>(&self, path: P) -> std::result::Result<(), std::io::Error> {
- let path = from_utf8(path)?;
+ fn remove_file>(&self, path: P) -> std::result::Result<(), std::io::Error> {
+ let path = path.as_ref();
self.cap_std.remove_file(path)
}
#[inline]
- fn remove_directory>(
- &self,
- path: P,
- ) -> std::result::Result<(), std::io::Error> {
- let path = from_utf8(path)?;
+ fn remove_directory>(&self, path: P) -> std::result::Result<(), std::io::Error> {
+ let path = path.as_ref();
self.cap_std.remove_directory(path)
}
}