From 5052be5b806b1704ec84165c811eff2b8fbae44d Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Tue, 15 Sep 2026 00:05:10 +0100 Subject: [PATCH] uucore: support fsext feature for more platforms The `fsext` feature builds successfully with Clippy on Haiku, NetBSD and OpenBSD: ```sh RUSTC_BOOTSTRAP=1 cargo clippy -q -Zbuild-std -p uucore --features fsext --all-targets --target x86_64-unknown-haiku --target i686-unknown-haiku --target i686-unknown-netbsd --target x86_64-unknown-netbsd --target x86_64-unknown-openbsd --target i686-unknown-openbsd ``` --- src/uucore/src/lib/features/fsext/mod.rs | 155 +++++++++++++++++++---- 1 file changed, 131 insertions(+), 24 deletions(-) diff --git a/src/uucore/src/lib/features/fsext/mod.rs b/src/uucore/src/lib/features/fsext/mod.rs index 5286089ad66..94425aab956 100644 --- a/src/uucore/src/lib/features/fsext/mod.rs +++ b/src/uucore/src/lib/features/fsext/mod.rs @@ -14,7 +14,10 @@ mod windows; const LINUX_MTAB: &str = "/etc/mtab"; #[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin"))] const LINUX_MOUNTINFO: &str = "/proc/self/mountinfo"; -#[cfg(all(unix, not(any(target_os = "aix", target_os = "redox"))))] +#[cfg(all( + unix, + not(any(target_os = "aix", target_os = "haiku", target_os = "redox")) +))] static MOUNT_OPT_BIND: &str = "bind"; #[cfg(any( @@ -65,6 +68,7 @@ pub use libc::statfs as StatFs; target_os = "aix", target_os = "netbsd", target_os = "dragonfly", + target_os = "haiku", target_os = "illumos", target_os = "solaris", target_os = "redox", @@ -82,6 +86,7 @@ pub use libc::statvfs as StatFs; pub use libc::statfs as statfs_fn; #[cfg(any( target_os = "aix", + target_os = "haiku", target_os = "netbsd", target_os = "illumos", target_os = "solaris", @@ -280,7 +285,10 @@ impl From for MountInfo { } } -#[cfg(all(unix, not(any(target_os = "aix", target_os = "redox"))))] +#[cfg(all( + unix, + not(any(target_os = "aix", target_os = "haiku", target_os = "redox")) +))] fn is_dummy_filesystem(fs_type: &str, mount_option: &str) -> bool { // spell-checker:disable match fs_type { @@ -303,14 +311,20 @@ fn is_dummy_filesystem(fs_type: &str, mount_option: &str) -> bool { // spell-checker:enable } -#[cfg(all(unix, not(any(target_os = "aix", target_os = "redox"))))] +#[cfg(all( + unix, + not(any(target_os = "aix", target_os = "haiku", target_os = "redox")) +))] fn is_remote_filesystem(dev_name: &str, fs_type: &str) -> bool { dev_name.find(':').is_some() || (dev_name.starts_with("//") && fs_type == "smbfs" || fs_type == "cifs") || dev_name == "-hosts" } -#[cfg(all(unix, not(any(target_os = "aix", target_os = "redox"))))] +#[cfg(all( + unix, + not(any(target_os = "aix", target_os = "haiku", target_os = "redox")) +))] fn mount_dev_id(mount_dir: &OsStr) -> String { use std::os::unix::fs::MetadataExt; @@ -353,6 +367,7 @@ use std::slice; #[cfg_attr( any( target_os = "aix", + target_os = "haiku", target_os = "redox", target_os = "illumos", target_os = "solaris", @@ -400,6 +415,7 @@ pub fn read_fs_list() -> UResult> { } #[cfg(any( target_os = "aix", + target_os = "haiku", target_os = "redox", target_os = "illumos", target_os = "solaris", @@ -428,7 +444,12 @@ impl FsUsage { pub fn new(statvfs: StatFs) -> Self { { #[cfg(all( - not(any(target_os = "freebsd", target_os = "openbsd")), + not(any( + target_os = "freebsd", + target_os = "haiku", + target_os = "netbsd", + target_os = "openbsd" + )), target_pointer_width = "64" ))] return Self { @@ -441,7 +462,12 @@ impl FsUsage { ffree: statvfs.f_ffree, }; #[cfg(all( - not(any(target_os = "freebsd", target_os = "openbsd")), + not(any( + target_os = "freebsd", + target_os = "haiku", + target_os = "netbsd", + target_os = "openbsd" + )), not(target_pointer_width = "64") ))] return Self { @@ -467,6 +493,26 @@ impl FsUsage { files: statvfs.f_files, ffree: statvfs.f_ffree.try_into().unwrap(), }; + #[cfg(target_os = "haiku")] + return Self { + blocksize: statvfs.block_size() as u64, + blocks: statvfs.f_blocks as u64, + bfree: statvfs.f_bfree as u64, + bavail: statvfs.f_bavail as u64, + bavail_top_bit_set: ((statvfs.f_bavail as u64) & (1u64.rotate_right(1))) != 0, + files: statvfs.f_files as u64, + ffree: statvfs.f_ffree as u64, + }; + #[cfg(target_os = "netbsd")] + return Self { + blocksize: statvfs.block_size() as u64, + blocks: statvfs.f_blocks, + bfree: statvfs.f_bfree, + bavail: statvfs.f_bavail, + bavail_top_bit_set: ((statvfs.f_bavail) & (1u64.rotate_right(1))) != 0, + files: statvfs.f_files, + ffree: statvfs.f_ffree, + }; #[cfg(target_os = "openbsd")] return Self { blocksize: statvfs.f_bsize.into(), @@ -524,6 +570,7 @@ impl FsMeta for StatFs { not(target_vendor = "apple"), not(target_os = "aix"), not(target_os = "freebsd"), + not(target_os = "haiku"), not(target_os = "netbsd"), not(target_os = "openbsd"), not(target_os = "illumos"), @@ -537,12 +584,12 @@ impl FsMeta for StatFs { #[cfg(all( not(target_env = "musl"), not(target_os = "freebsd"), - not(target_os = "netbsd"), not(target_os = "redox"), not(target_os = "cygwin"), any( target_arch = "s390x", target_vendor = "apple", + all(target_os = "haiku", not(target_pointer_width = "64")), target_os = "openbsd", not(target_pointer_width = "64") ) @@ -552,54 +599,103 @@ impl FsMeta for StatFs { target_env = "musl", target_os = "aix", target_os = "freebsd", - target_os = "netbsd", target_os = "illumos", target_os = "solaris", target_os = "redox", target_os = "cygwin", + all(target_os = "haiku", target_pointer_width = "64"), + all(target_os = "netbsd", target_pointer_width = "64"), ))] return self.f_bsize.try_into().unwrap(); } fn total_blocks(&self) -> u64 { - #[cfg(target_pointer_width = "64")] + #[cfg(any( + target_os = "netbsd", + target_os = "openbsd", + all(not(target_os = "haiku"), target_pointer_width = "64") + ))] return self.f_blocks; - #[cfg(not(target_pointer_width = "64"))] + #[cfg(all( + not(any(target_os = "haiku", target_os = "netbsd", target_os = "openbsd")), + not(target_pointer_width = "64") + ))] return self.f_blocks.into(); + #[cfg(target_os = "haiku")] + return self.f_blocks.try_into().unwrap(); } fn free_blocks(&self) -> u64 { - #[cfg(target_pointer_width = "64")] + #[cfg(any( + target_os = "netbsd", + target_os = "openbsd", + all(not(target_os = "haiku"), target_pointer_width = "64") + ))] return self.f_bfree; - #[cfg(not(target_pointer_width = "64"))] + #[cfg(all( + not(any(target_os = "haiku", target_os = "netbsd", target_os = "openbsd")), + not(target_pointer_width = "64") + ))] return self.f_bfree.into(); + #[cfg(target_os = "haiku")] + return self.f_bfree.try_into().unwrap(); } fn avail_blocks(&self) -> u64 { - #[cfg(all( - not(target_os = "freebsd"), - not(target_os = "openbsd"), - target_pointer_width = "64" + #[cfg(any( + target_os = "netbsd", + all( + not(target_os = "freebsd"), + not(target_os = "haiku"), + not(target_os = "openbsd"), + target_pointer_width = "64" + ) ))] return self.f_bavail; #[cfg(all( not(target_os = "freebsd"), + not(target_os = "haiku"), + not(target_os = "freebsd"), + not(target_os = "netbsd"), not(target_os = "openbsd"), not(target_pointer_width = "64") ))] return self.f_bavail.into(); - #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + #[cfg(any(target_os = "freebsd", target_os = "haiku", target_os = "openbsd"))] return self.f_bavail.try_into().unwrap(); } fn total_file_nodes(&self) -> u64 { - #[cfg(target_pointer_width = "64")] + #[cfg(any( + target_os = "netbsd", + target_os = "openbsd", + all(not(target_os = "haiku"), target_pointer_width = "64") + ))] return self.f_files; - #[cfg(not(target_pointer_width = "64"))] + #[cfg(all( + not(any(target_os = "haiku", target_os = "netbsd", target_os = "openbsd")), + not(target_pointer_width = "64") + ))] return self.f_files.into(); + #[cfg(target_os = "haiku")] + return self.f_files.try_into().unwrap(); } fn free_file_nodes(&self) -> u64 { - #[cfg(all(not(target_os = "freebsd"), target_pointer_width = "64"))] + #[cfg(any( + target_os = "netbsd", + target_os = "openbsd", + all( + not(target_os = "freebsd"), + not(target_os = "haiku"), + target_pointer_width = "64" + ) + ))] return self.f_ffree; - #[cfg(all(not(target_os = "freebsd"), not(target_pointer_width = "64")))] + #[cfg(all( + not(target_os = "freebsd"), + not(target_os = "haiku"), + not(target_os = "netbsd"), + not(target_os = "openbsd"), + not(target_pointer_width = "64") + ))] return self.f_ffree.into(); - #[cfg(target_os = "freebsd")] + #[cfg(any(target_os = "freebsd", target_os = "haiku"))] return self.f_ffree.try_into().unwrap(); } #[cfg(any( @@ -648,7 +744,12 @@ impl FsMeta for StatFs { } /// The preferred transfer size, which on Linux is `f_bsize`. - #[cfg(any(target_os = "aix", target_os = "linux", target_os = "android"))] + #[cfg(any( + target_os = "aix", + target_os = "haiku", + target_os = "linux", + target_os = "android" + ))] #[allow(clippy::unnecessary_cast)] fn io_size(&self) -> u64 { self.f_bsize as u64 @@ -666,6 +767,7 @@ impl FsMeta for StatFs { target_vendor = "apple", target_os = "aix", target_os = "freebsd", + target_os = "haiku", target_os = "linux", target_os = "android", target_os = "netbsd" @@ -717,6 +819,7 @@ impl FsMeta for StatFs { #[cfg(any( target_os = "aix", target_os = "freebsd", + target_os = "haiku", target_os = "netbsd", target_os = "openbsd" ))] @@ -729,6 +832,7 @@ impl FsMeta for StatFs { target_vendor = "apple", target_os = "aix", target_os = "freebsd", + target_os = "haiku", target_os = "linux", target_os = "android", target_os = "netbsd", @@ -1077,7 +1181,10 @@ mod tests { } #[test] - #[cfg(all(unix, not(any(target_os = "aix", target_os = "redox"))))] + #[cfg(all( + unix, + not(any(target_os = "aix", target_os = "haiku", target_os = "redox")) + ))] // spell-checker:ignore (word) binfmt fn test_binfmt_misc_is_dummy() { use super::is_dummy_filesystem;