mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-01 05:27:45 +00:00
df: better error message when executed in a chroot without /proc #3601
This commit is contained in:
parent
37b754f462
commit
9d554751ca
3 changed files with 36 additions and 21 deletions
|
@ -14,7 +14,7 @@ mod table;
|
||||||
use blocks::HumanReadable;
|
use blocks::HumanReadable;
|
||||||
use table::HeaderMode;
|
use table::HeaderMode;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{UError, UResult, USimpleError};
|
use uucore::error::{UError, UIoError, UResult, USimpleError};
|
||||||
use uucore::fsext::{read_fs_list, MountInfo};
|
use uucore::fsext::{read_fs_list, MountInfo};
|
||||||
use uucore::parse_size::ParseSizeError;
|
use uucore::parse_size::ParseSizeError;
|
||||||
use uucore::{format_usage, show};
|
use uucore::{format_usage, show};
|
||||||
|
@ -333,7 +333,7 @@ fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
|
||||||
/// `opt` excludes certain filesystems from consideration and allows for the synchronization of filesystems before running; see
|
/// `opt` excludes certain filesystems from consideration and allows for the synchronization of filesystems before running; see
|
||||||
/// [`Options`] for more information.
|
/// [`Options`] for more information.
|
||||||
|
|
||||||
fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> {
|
fn get_all_filesystems(opt: &Options) -> Result<Vec<Filesystem>, std::io::Error> {
|
||||||
// Run a sync call before any operation if so instructed.
|
// Run a sync call before any operation if so instructed.
|
||||||
if opt.sync {
|
if opt.sync {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
|
@ -349,19 +349,19 @@ fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> {
|
||||||
//
|
//
|
||||||
// Filesystems excluded by the command-line options are
|
// Filesystems excluded by the command-line options are
|
||||||
// not considered.
|
// not considered.
|
||||||
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list(), opt);
|
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list()?, opt);
|
||||||
|
|
||||||
// Convert each `MountInfo` into a `Filesystem`, which contains
|
// Convert each `MountInfo` into a `Filesystem`, which contains
|
||||||
// both the mount information and usage information.
|
// both the mount information and usage information.
|
||||||
mounts
|
Ok(mounts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|m| Filesystem::new(m, None))
|
.filter_map(|m| Filesystem::new(m, None))
|
||||||
.filter(|fs| opt.show_all_fs || fs.usage.blocks > 0)
|
.filter(|fs| opt.show_all_fs || fs.usage.blocks > 0)
|
||||||
.collect()
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For each path, get the filesystem that contains that path.
|
/// For each path, get the filesystem that contains that path.
|
||||||
fn get_named_filesystems<P>(paths: &[P], opt: &Options) -> Vec<Filesystem>
|
fn get_named_filesystems<P>(paths: &[P], opt: &Options) -> Result<Vec<Filesystem>, std::io::Error>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
|
@ -371,7 +371,7 @@ where
|
||||||
// considered. The "lofs" filesystem is a loopback
|
// considered. The "lofs" filesystem is a loopback
|
||||||
// filesystem present on Solaris and FreeBSD systems. It
|
// filesystem present on Solaris and FreeBSD systems. It
|
||||||
// is similar to a symbolic link.
|
// is similar to a symbolic link.
|
||||||
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list(), opt)
|
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list()?, opt)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|mi| mi.fs_type != "lofs" && !mi.dummy)
|
.filter(|mi| mi.fs_type != "lofs" && !mi.dummy)
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -381,7 +381,7 @@ where
|
||||||
// this happens if the file system type doesn't exist
|
// this happens if the file system type doesn't exist
|
||||||
if mounts.is_empty() {
|
if mounts.is_empty() {
|
||||||
show!(USimpleError::new(1, "no file systems processed"));
|
show!(USimpleError::new(1, "no file systems processed"));
|
||||||
return result;
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert each path into a `Filesystem`, which contains
|
// Convert each path into a `Filesystem`, which contains
|
||||||
|
@ -402,7 +402,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -443,7 +443,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
// Get the list of filesystems to display in the output table.
|
// Get the list of filesystems to display in the output table.
|
||||||
let filesystems: Vec<Filesystem> = match matches.values_of(OPT_PATHS) {
|
let filesystems: Vec<Filesystem> = match matches.values_of(OPT_PATHS) {
|
||||||
None => {
|
None => {
|
||||||
let filesystems = get_all_filesystems(&opt);
|
let filesystems = match get_all_filesystems(&opt) {
|
||||||
|
Ok(filesystems) => filesystems,
|
||||||
|
Err(error) => {
|
||||||
|
return Err(UIoError::new(
|
||||||
|
error.kind(),
|
||||||
|
format!("cannot read table of mounted file systems"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if filesystems.is_empty() {
|
if filesystems.is_empty() {
|
||||||
return Err(USimpleError::new(1, "no file systems processed"));
|
return Err(USimpleError::new(1, "no file systems processed"));
|
||||||
|
@ -453,7 +461,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
}
|
}
|
||||||
Some(paths) => {
|
Some(paths) => {
|
||||||
let paths: Vec<&str> = paths.collect();
|
let paths: Vec<&str> = paths.collect();
|
||||||
let filesystems = get_named_filesystems(&paths, &opt);
|
let filesystems = match get_named_filesystems(&paths, &opt) {
|
||||||
|
Ok(filesystems) => filesystems,
|
||||||
|
Err(error) => {
|
||||||
|
return Err(UIoError::new(
|
||||||
|
error.kind(),
|
||||||
|
format!("cannot read table of mounted file systems"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// This can happen if paths are given as command-line arguments
|
// This can happen if paths are given as command-line arguments
|
||||||
// but none of the paths exist.
|
// but none of the paths exist.
|
||||||
|
|
|
@ -501,7 +501,7 @@ impl Stater {
|
||||||
// mount points aren't displayed when showing filesystem information
|
// mount points aren't displayed when showing filesystem information
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let mut mount_list = read_fs_list()
|
let mut mount_list = read_fs_list()?
|
||||||
.iter()
|
.iter()
|
||||||
.map(|mi| mi.mount_dir.clone())
|
.map(|mi| mi.mount_dir.clone())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
|
@ -405,22 +405,21 @@ use std::ptr;
|
||||||
))]
|
))]
|
||||||
use std::slice;
|
use std::slice;
|
||||||
/// Read file system list.
|
/// Read file system list.
|
||||||
pub fn read_fs_list() -> Vec<MountInfo> {
|
pub fn read_fs_list() -> Result<Vec<MountInfo>, std::io::Error> {
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
{
|
{
|
||||||
let (file_name, f) = File::open(LINUX_MOUNTINFO)
|
let (file_name, f) = File::open(LINUX_MOUNTINFO)
|
||||||
.map(|f| (LINUX_MOUNTINFO, f))
|
.map(|f| (LINUX_MOUNTINFO, f))
|
||||||
.or_else(|_| File::open(LINUX_MTAB).map(|f| (LINUX_MTAB, f)))
|
.or_else(|_| File::open(LINUX_MTAB).map(|f| (LINUX_MTAB, f)))?;
|
||||||
.expect("failed to find mount list files");
|
|
||||||
let reader = BufReader::new(f);
|
let reader = BufReader::new(f);
|
||||||
reader
|
Ok(reader
|
||||||
.lines()
|
.lines()
|
||||||
.filter_map(|line| line.ok())
|
.filter_map(|line| line.ok())
|
||||||
.filter_map(|line| {
|
.filter_map(|line| {
|
||||||
let raw_data = line.split_whitespace().collect::<Vec<&str>>();
|
let raw_data = line.split_whitespace().collect::<Vec<&str>>();
|
||||||
MountInfo::new(file_name, &raw_data)
|
MountInfo::new(file_name, &raw_data)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
|
@ -435,10 +434,10 @@ pub fn read_fs_list() -> Vec<MountInfo> {
|
||||||
crash!(1, "get_mount_info() failed");
|
crash!(1, "get_mount_info() failed");
|
||||||
}
|
}
|
||||||
let mounts = unsafe { slice::from_raw_parts(mount_buffer_ptr, len as usize) };
|
let mounts = unsafe { slice::from_raw_parts(mount_buffer_ptr, len as usize) };
|
||||||
mounts
|
Ok(mounts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| MountInfo::from(*m))
|
.map(|m| MountInfo::from(*m))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
|
@ -482,12 +481,12 @@ pub fn read_fs_list() -> Vec<MountInfo> {
|
||||||
unsafe {
|
unsafe {
|
||||||
FindVolumeClose(find_handle);
|
FindVolumeClose(find_handle);
|
||||||
}
|
}
|
||||||
mounts
|
Ok(mounts)
|
||||||
}
|
}
|
||||||
#[cfg(any(target_os = "redox", target_os = "illumos", target_os = "solaris"))]
|
#[cfg(any(target_os = "redox", target_os = "illumos", target_os = "solaris"))]
|
||||||
{
|
{
|
||||||
// No method to read mounts, yet
|
// No method to read mounts, yet
|
||||||
Vec::new()
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue