mirror of
https://github.com/uutils/coreutils
synced 2024-10-07 00:19:14 +00:00
Find MountInfo properly when symlink is used (#4929)
* Find MountInfo properly when symlink is entered According to GNU implementation the entered path is being compared with the canonicalized device name in MountInfo. Co-authored-by: Frantisek Kropac <kropac.ff@gmail.com> Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
This commit is contained in:
parent
60e797ea57
commit
ad96a1b8a0
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2562,6 +2562,7 @@ name = "uu_df"
|
|||
version = "0.0.19"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"tempfile",
|
||||
"unicode-width",
|
||||
"uucore",
|
||||
]
|
||||
|
|
|
@ -19,6 +19,9 @@ clap = { workspace = true }
|
|||
uucore = { workspace = true, features = ["libc", "fsext"] }
|
||||
unicode-width = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
[[bin]]
|
||||
name = "df"
|
||||
path = "src/main.rs"
|
||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) struct Filesystem {
|
|||
/// This function returns the element of `mounts` on which `path` is
|
||||
/// mounted. If there are no matches, this function returns
|
||||
/// [`None`]. If there are two or more matches, then the single
|
||||
/// [`MountInfo`] with the longest mount directory is returned.
|
||||
/// [`MountInfo`] with the device name corresponding to the entered path.
|
||||
///
|
||||
/// If `canonicalize` is `true`, then the `path` is canonicalized
|
||||
/// before checking whether it matches any mount directories.
|
||||
|
@ -68,9 +68,19 @@ where
|
|||
path.as_ref().to_path_buf()
|
||||
};
|
||||
|
||||
// Find the potential mount point that matches entered path
|
||||
let maybe_mount_point = mounts
|
||||
.iter()
|
||||
.find(|mi| mi.dev_name.eq(&path.to_string_lossy()));
|
||||
// Create pair MountInfo, canonicalized device name
|
||||
// TODO Abstract from accessing real filesystem to
|
||||
// make code more testable
|
||||
.map(|m| (m, std::fs::canonicalize(&m.dev_name)))
|
||||
// Ignore non existing paths
|
||||
.filter(|m| m.1.is_ok())
|
||||
.map(|m| (m.0, m.1.ok().unwrap()))
|
||||
// Try to find canonicalized device name corresponding to entered path
|
||||
.find(|m| m.1.eq(&path))
|
||||
.map(|m| m.0);
|
||||
|
||||
maybe_mount_point.or_else(|| {
|
||||
mounts
|
||||
|
@ -211,10 +221,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dev_name_match() {
|
||||
let tmp = tempfile::TempDir::new().expect("Failed to create temp dir");
|
||||
let dev_name = std::fs::canonicalize(tmp.path())
|
||||
.expect("Failed to canonicalize tmp path")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
let mut mount_info = mount_info("/foo");
|
||||
mount_info.dev_name = "/dev/sda2".to_string();
|
||||
mount_info.dev_name = dev_name.clone();
|
||||
let mounts = [mount_info];
|
||||
let actual = mount_info_from_path(&mounts, "/dev/sda2", false).unwrap();
|
||||
let actual = mount_info_from_path(&mounts, dev_name, false).unwrap();
|
||||
assert!(mount_info_eq(actual, &mounts[0]));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue