1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

fix(df): Improve MacOSX support

This commit is contained in:
Sylvestre Ledru 2020-04-21 00:28:53 +02:00 committed by Roy Ivy III
parent dd1a212550
commit 8545f03e0f

View file

@ -25,25 +25,39 @@ use kernel32::{
FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetDiskFreeSpaceW, GetDriveTypeW, FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetDiskFreeSpaceW, GetDriveTypeW,
GetLastError, GetVolumeInformationW, GetVolumePathNamesForVolumeNameW, QueryDosDeviceW, GetLastError, GetVolumeInformationW, GetVolumePathNamesForVolumeNameW, QueryDosDeviceW,
}; };
#[cfg(unix)]
#[cfg(target_os = "macos")]
use libc::statfs;
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::ffi::CString; use std::ffi::CString;
#[cfg(unix)] use std::{env, mem};
#[cfg(target_os = "macos")]
use libc::c_int;
#[cfg(target_os = "macos")]
use libc::statfs;
#[cfg(target_os = "macos")]
use std::ffi::CStr;
#[cfg(target_os = "macos")]
use std::ptr;
#[cfg(target_os = "macos")]
use std::slice;
#[cfg(target_os = "linux")]
use std::fs::File; use std::fs::File;
#[cfg(target_os = "linux")]
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
#[cfg(windows)] #[cfg(windows)]
use std::os::windows::prelude::*; use std::os::windows::prelude::*;
use std::{env, mem};
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Show information about the file system on which each FILE resides,\n\ static ABOUT: &str = "Show information about the file system on which each FILE resides,\n\
or all file systems by default."; or all file systems by default.";
const EXIT_OK: i32 = 0; static EXIT_OK: i32 = 0;
#[cfg(any(target_os = "freebsd", target_os = "macos", target_os = "windows"))]
static EXIT_ERR: i32 = 1;
#[cfg(windows)] #[cfg(windows)]
const MAX_PATH: usize = 266; const MAX_PATH: usize = 266;
@ -493,10 +507,10 @@ fn read_fs_list() -> Vec<MountInfo> {
crash!(EXIT_ERR, "getmntinfo failed"); crash!(EXIT_ERR, "getmntinfo failed");
} }
let mounts = unsafe { slice::from_raw_parts(mptr, len as usize) }; let mounts = unsafe { slice::from_raw_parts(mptr, len as usize) };
return mounts mounts
.into_iter() .iter()
.map(|m| MountInfo::from(*m)) .map(|m| MountInfo::from(*m))
.collect::<Vec<_>>(); .collect::<Vec<_>>()
} }
#[cfg(windows)] #[cfg(windows)]
{ {
@ -543,7 +557,6 @@ fn read_fs_list() -> Vec<MountInfo> {
} }
} }
#[allow(clippy::map_entry)]
fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> { fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
vmi.into_iter() vmi.into_iter()
.filter_map(|mi| { .filter_map(|mi| {
@ -559,15 +572,17 @@ fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
.fold( .fold(
HashMap::<String, Cell<MountInfo>>::new(), HashMap::<String, Cell<MountInfo>>::new(),
|mut acc, (id, mi)| { |mut acc, (id, mi)| {
if acc.contains_key(&id) { #[allow(clippy::map_entry)]
let seen = acc.get(&id).unwrap().replace(mi.clone()); {
let target_nearer_root = seen.mount_dir.len() > mi.mount_dir.len(); if acc.contains_key(&id) {
// With bind mounts, prefer items nearer the root of the source let seen = acc.get(&id).unwrap().replace(mi.clone());
let source_below_root = !seen.mount_root.is_empty() let target_nearer_root = seen.mount_dir.len() > mi.mount_dir.len();
&& !mi.mount_root.is_empty() // With bind mounts, prefer items nearer the root of the source
&& seen.mount_root.len() < mi.mount_root.len(); let source_below_root = !seen.mount_root.is_empty()
// let "real" devices with '/' in the name win. && !mi.mount_root.is_empty()
if (!mi.dev_name.starts_with('/') || seen.dev_name.starts_with('/')) && seen.mount_root.len() < mi.mount_root.len();
// let "real" devices with '/' in the name win.
if (!mi.dev_name.starts_with('/') || seen.dev_name.starts_with('/'))
// let points towards the root of the device win. // let points towards the root of the device win.
&& (!target_nearer_root || source_below_root) && (!target_nearer_root || source_below_root)
// let an entry overmounted on a new device win... // let an entry overmounted on a new device win...
@ -577,13 +592,14 @@ fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
inaccurate mount lists, seen with some chroot inaccurate mount lists, seen with some chroot
environments for example. */ environments for example. */
|| seen.mount_dir != mi.mount_dir) || seen.mount_dir != mi.mount_dir)
{ {
acc.get(&id).unwrap().replace(seen); acc.get(&id).unwrap().replace(seen);
}
} else {
acc.insert(id, Cell::new(mi));
} }
} else { acc
acc.insert(id, Cell::new(mi));
} }
acc
}, },
) )
.into_iter() .into_iter()