Skip to content

Commit f07670b

Browse files
committed
rm: Check filesystem checks in rm command
- Rename `validate_single_filesystem` to `check_one_fs` for improved clarity and alignment with its functionality. - Refactore `check_one_fs` to directly handle options such as `--one-file-system` and `--preserve-root=all` and return detailed error messages when the conditions are not met. - Integrate `check_one_fs` into `remove_dir_recursive` and `handle_dir` for consistent handling of files and directories on different file systems.
1 parent be69f52 commit f07670b

File tree

3 files changed

+36
-42
lines changed

3 files changed

+36
-42
lines changed

src/uu/rm/src/rm.rs

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,17 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
431431
}
432432
}
433433

434+
if let Err(additional_reason) = check_one_fs(path, options) {
435+
if !additional_reason.is_empty() {
436+
show_error!("{}", additional_reason);
437+
}
438+
show_error!(
439+
"skipping {}, since it's on a different device",
440+
path.quote()
441+
);
442+
return true;
443+
}
444+
434445
// Base case 1: this is a file or a symbolic link.
435446
//
436447
// The symbolic link case is important because it could be a link to
@@ -525,10 +536,16 @@ fn mount_for_path<'a>(path: &Path, mounts: &'a [MountInfo]) -> Option<&'a MountI
525536
best.map(|(mi, _len)| mi)
526537
}
527538

528-
/// Validates that a path is on the same file system as its parent.
539+
/// Check if a path is on the same file system when `--one-file-system` or `--preserve-root=all` options are enabled.
529540
/// Return `OK(())` if the path is on the same file system,
530541
/// or an additional error describing why it should be skipped.
531-
fn validate_single_filesystem(path: &Path) -> Result<(), String> {
542+
fn check_one_fs(path: &Path, options: &Options) -> Result<(), String> {
543+
// If neither `--one-file-system` nor `--preserve-root=all` is active,
544+
// always proceed
545+
if !options.one_fs && options.preserve_root != PreserveRoot::YesAll {
546+
return Ok(());
547+
}
548+
532549
// Read mount information
533550
let fs_list = read_fs_list().map_err(|err| format!("cannot read mount info: {err}"))?;
534551

@@ -553,42 +570,20 @@ fn validate_single_filesystem(path: &Path) -> Result<(), String> {
553570
Ok(())
554571
}
555572

556-
/// Check if a path is on the same file system when `--one-file-system` or `--preserve-root=all` options are enabled.
557-
/// Return `true` if the path can be processed, `false` if it should be skipped.
558-
fn check_one_fs(path: &Path, options: &Options) -> bool {
559-
// If neither `--one-file-system` nor `--preserve-root=all` is active,
560-
// always proceed
561-
if !options.one_fs && options.preserve_root != PreserveRoot::YesAll {
562-
return true;
563-
}
564-
565-
let result = validate_single_filesystem(path);
566-
if result.is_ok() {
567-
return true;
568-
}
573+
fn handle_dir(path: &Path, options: &Options) -> bool {
574+
let mut had_err = false;
569575

570-
if let Err(additional_reason) = result {
576+
if let Err(additional_reason) = check_one_fs(path, options) {
571577
if !additional_reason.is_empty() {
572578
show_error!("{}", additional_reason);
573579
}
574-
}
575-
576-
show_error!(
577-
"skipping {}, since it's on a different device",
578-
path.quote()
579-
);
580-
581-
if options.preserve_root == PreserveRoot::YesAll {
582-
show_error!("and --preserve-root=all is in effect");
583-
}
584-
585-
false
586-
}
587-
588-
fn handle_dir(path: &Path, options: &Options) -> bool {
589-
let mut had_err = false;
590-
591-
if !check_one_fs(path, options) {
580+
show_error!(
581+
"skipping {}, since it's on a different device",
582+
path.quote()
583+
);
584+
if options.preserve_root == PreserveRoot::YesAll {
585+
show_error!("and --preserve-root=all is in effect");
586+
}
592587
return true;
593588
}
594589

tests/by-util/test_rm.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -971,8 +971,8 @@ fn test_rm_one_file_system() {
971971
// Define paths for temporary files and directories
972972
let img_path = "fs.img";
973973
let mount_point = "fs";
974-
let src_dir = "a/b";
975-
let bind_mount_point = "a";
974+
let remove_dir = "a";
975+
let bind_mount_point = "a/b";
976976

977977
at.touch(img_path);
978978

@@ -991,8 +991,8 @@ fn test_rm_one_file_system() {
991991
scene.cmd("/sbin/mkfs.ext4").arg(img_path).succeeds();
992992

993993
// Prepare directory structure
994-
at.mkdir_all(src_dir);
995994
at.mkdir_all(mount_point);
995+
at.mkdir_all(bind_mount_point);
996996

997997
// Mount as loop device
998998
scene
@@ -1012,7 +1012,7 @@ fn test_rm_one_file_system() {
10121012
// Run the test
10131013
scene
10141014
.ucmd()
1015-
.args(&["--one-file-system", "-rf", bind_mount_point])
1015+
.args(&["--one-file-system", "-rf", remove_dir])
10161016
.fails()
10171017
.stderr_contains(format!("rm: skipping '{}'", bind_mount_point));
10181018

@@ -1040,8 +1040,7 @@ fn test_rm_preserve_root() {
10401040
// Define paths for temporary files and directories
10411041
let img_path = "fs.img";
10421042
let mount_point = "fs";
1043-
let src_dir = "a/b";
1044-
let bind_mount_point = "a";
1043+
let bind_mount_point = "a/b";
10451044

10461045
at.touch(img_path);
10471046

@@ -1060,8 +1059,8 @@ fn test_rm_preserve_root() {
10601059
scene.cmd("/sbin/mkfs.ext4").arg(img_path).succeeds();
10611060

10621061
// Prepare directory structure
1063-
at.mkdir_all(src_dir);
10641062
at.mkdir_all(mount_point);
1063+
at.mkdir_all(bind_mount_point);
10651064

10661065
// Mount as loop device
10671066
scene

util/build-gnu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ sed -i -e "s|removed directory 'a/'|removed directory 'a'|g" tests/rm/v-slash.sh
207207

208208
if test "$(grep -c 'rm: skipping ' tests/rm/one-file-system.sh)" -eq 1; then
209209
# Do it only once.
210-
sed -i -e "s|rm: skipping 'a/b'|rm: skipping 'a'|g" -e "s/ >> exp/ > exp/g" -e "s|rm: and --preserve-root=all is in effect|rm: skipping 'a/b', since it's on a different device\nrm: and --preserve-root=all is in effect|g" tests/rm/one-file-system.sh
210+
sed -i -e "s/ >> exp/ > exp/g" -e "s|rm: and --preserve-root=all is in effect|rm: skipping 'a/b', since it's on a different device\nrm: and --preserve-root=all is in effect|g" tests/rm/one-file-system.sh
211211
fi
212212

213213
# 'rel' doesn't exist. Our implementation is giving a better message.

0 commit comments

Comments
 (0)