Skip to content

Commit 463986e

Browse files
committed
[cap-primitives] add support for illumos
Get the cap-primitives library building and passing all tests on illumos. There were just a couple of minor tweaks required. I also ran into an issue where the minimum version of `ipnet` required was too old, so I took the liberty to bump it to 2.5.0 which has `IpNet::new`. The note in `dir_entry.rs` is copied over from Rust's std: https://doc.rust-lang.org/std/fs/struct.DirEntry.html#method.file_type
1 parent 9ec2ba7 commit 463986e

File tree

5 files changed

+28
-7
lines changed

5 files changed

+28
-7
lines changed

cap-primitives/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ edition = "2021"
1515
[dependencies]
1616
ambient-authority = "0.0.2"
1717
arbitrary = { version = "1.0.0", optional = true, features = ["derive"] }
18-
ipnet = "2.3.0"
18+
ipnet = "2.5.0"
1919
maybe-owned = "0.3.4"
2020
fs-set-times = "0.20.0"
2121
io-extras = "0.18.0"
@@ -25,7 +25,7 @@ io-lifetimes = { version = "2.0.0", default-features = false }
2525
cap-tempfile = { path = "../cap-tempfile" }
2626

2727
[target.'cfg(not(windows))'.dependencies]
28-
rustix = { version = "0.38.32", features = ["fs", "process", "procfs", "termios", "time"] }
28+
rustix = { version = "0.38.38", features = ["fs", "process", "procfs", "termios", "time"] }
2929

3030
[target.'cfg(windows)'.dependencies]
3131
winx = "0.36.0"

cap-primitives/src/fs/dir_entry.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ impl DirEntry {
8282
/// Returns the file type for the file that this entry points at.
8383
///
8484
/// This corresponds to [`std::fs::DirEntry::file_type`].
85+
///
86+
/// # Platform-specific behavior
87+
///
88+
/// On Windows and most Unix platforms this function is free (no extra system calls needed), but
89+
/// some Unix platforms may require the equivalent call to `metadata` to learn about the target
90+
/// file type.
8591
#[inline]
8692
pub fn file_type(&self) -> io::Result<FileType> {
8793
self.inner.file_type()

cap-primitives/src/rustix/fs/dir_entry_inner.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::fs::{
2-
FileType, FollowSymlinks, ImplFileTypeExt, Metadata, MetadataExt, OpenOptions, ReadDir,
3-
ReadDirInner,
2+
FileType, FollowSymlinks, Metadata, MetadataExt, OpenOptions, ReadDir, ReadDirInner,
43
};
54
use rustix::fs::DirEntry;
65
use std::ffi::{OsStr, OsString};
@@ -41,9 +40,12 @@ impl DirEntryInner {
4140
self.read_dir.remove_dir(self.file_name_bytes())
4241
}
4342

43+
#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
4444
#[inline]
4545
#[allow(clippy::unnecessary_wraps)]
4646
pub(crate) fn file_type(&self) -> io::Result<FileType> {
47+
use crate::fs::ImplFileTypeExt;
48+
4749
Ok(match self.rustix.file_type() {
4850
rustix::fs::FileType::Directory => FileType::dir(),
4951
rustix::fs::FileType::RegularFile => FileType::file(),
@@ -58,6 +60,13 @@ impl DirEntryInner {
5860
})
5961
}
6062

63+
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
64+
#[inline]
65+
pub(crate) fn file_type(&self) -> io::Result<FileType> {
66+
// These platforms don't have the file type on the dirent, so we must lstat the file.
67+
self.metadata().map(|m| m.file_type())
68+
}
69+
6170
#[inline]
6271
pub(crate) fn file_name(&self) -> OsString {
6372
self.file_name_bytes().to_os_string()

cap-primitives/src/rustix/fs/dir_utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ pub(crate) const fn target_o_path() -> OFlags {
143143
target_os = "netbsd",
144144
target_os = "openbsd",
145145
target_os = "wasi",
146+
target_os = "illumos",
147+
target_os = "solaris",
146148
))]
147149
{
148150
OFlags::empty()

cap-primitives/src/rustix/fs/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,13 @@ fn tty_path() {
142142
#[cfg(unix)]
143143
use std::os::unix::fs::FileTypeExt;
144144

145-
// On FreeBSD, /dev/{tty,stdin,stdout,stderr} are aliases to different real
146-
// devices.
147145
let paths: &[&str] = if cfg!(target_os = "freebsd") {
146+
// On FreeBSD, /dev/{tty,stdin,stdout,stderr} are aliases to different
147+
// real devices.
148148
&["/dev/ttyv0", "/dev/pts/0"]
149+
} else if cfg!(target_os = "illumos") {
150+
// On illumos, /dev/std{in,out,err} only exist if they're open.
151+
&["/dev/tty", "/dev/pts/0"]
149152
} else {
150153
&["/dev/tty", "/dev/stdin", "/dev/stdout", "/dev/stderr"]
151154
};
@@ -162,7 +165,8 @@ fn tty_path() {
162165
.as_ref()
163166
.map(std::fs::canonicalize)
164167
.map(Result::unwrap),
165-
Some(canonical)
168+
Some(canonical),
169+
"for path {path}, file_path matches canonicalized path"
166170
);
167171
}
168172
}

0 commit comments

Comments
 (0)