Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions docs/src/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ packages.

`mv` can display a progress bar when the `-g`/`--progress` flag is set.

## `rm`

`rm` can display a progress bar when the `-g`/`--progress` flag is set.

## `hashsum`

This utility does not exist in GNU coreutils. `hashsum` is a utility that
Expand Down
1 change: 1 addition & 0 deletions src/uu/rm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ thiserror = { workspace = true }
clap = { workspace = true }
uucore = { workspace = true, features = ["fs", "parser", "safe-traversal"] }
fluent = { workspace = true }
indicatif = { workspace = true }

[target.'cfg(unix)'.dependencies]
libc = { workspace = true }
Expand Down
4 changes: 4 additions & 0 deletions src/uu/rm/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ rm-help-preserve-root = do not remove '/' (default)
rm-help-recursive = remove directories and their contents recursively
rm-help-dir = remove empty directories
rm-help-verbose = explain what is being done
rm-help-progress = display a progress bar. Note: this feature is not supported by GNU coreutils.

# Progress messages
rm-progress-removing = Removing

# Error messages
rm-error-missing-operand = missing operand
Expand Down
4 changes: 4 additions & 0 deletions src/uu/rm/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ rm-help-preserve-root = ne pas supprimer '/' (par défaut)
rm-help-recursive = supprimer les répertoires et leur contenu récursivement
rm-help-dir = supprimer les répertoires vides
rm-help-verbose = expliquer ce qui est fait
rm-help-progress = afficher une barre de progression. Note : cette fonctionnalité n'est pas supportée par GNU coreutils.

# Messages de progression
rm-progress-removing = Suppression

# Messages d'erreur
rm-error-missing-operand = opérande manquant
Expand Down
29 changes: 25 additions & 4 deletions src/uu/rm/src/platform/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// spell-checker:ignore fstatat unlinkat

use indicatif::ProgressBar;
use std::ffi::OsStr;
use std::fs;
use std::path::Path;
Expand All @@ -28,14 +29,22 @@ pub fn is_readable(path: &Path) -> bool {
}

/// Remove a single file using safe traversal
pub fn safe_remove_file(path: &Path, options: &Options) -> Option<bool> {
pub fn safe_remove_file(
path: &Path,
options: &Options,
progress_bar: Option<&ProgressBar>,
) -> Option<bool> {
let parent = path.parent()?;
let file_name = path.file_name()?;

let dir_fd = DirFd::open(parent).ok()?;

match dir_fd.unlink_at(file_name, false) {
Ok(_) => {
// Update progress bar for file removal
if let Some(pb) = progress_bar {
pb.inc(1);
}
verbose_removed_file(path, options);
Some(false)
}
Expand All @@ -51,14 +60,22 @@ pub fn safe_remove_file(path: &Path, options: &Options) -> Option<bool> {
}

/// Remove an empty directory using safe traversal
pub fn safe_remove_empty_dir(path: &Path, options: &Options) -> Option<bool> {
pub fn safe_remove_empty_dir(
path: &Path,
options: &Options,
progress_bar: Option<&ProgressBar>,
) -> Option<bool> {
let parent = path.parent()?;
let dir_name = path.file_name()?;

let dir_fd = DirFd::open(parent).ok()?;

match dir_fd.unlink_at(dir_name, true) {
Ok(_) => {
// Update progress bar for directory removal
if let Some(pb) = progress_bar {
pb.inc(1);
}
verbose_removed_directory(path, options);
Some(false)
}
Expand Down Expand Up @@ -172,12 +189,16 @@ pub fn remove_dir_with_special_cases(path: &Path, options: &Options, error_occur
}
}

pub fn safe_remove_dir_recursive(path: &Path, options: &Options) -> bool {
pub fn safe_remove_dir_recursive(
path: &Path,
options: &Options,
progress_bar: Option<&ProgressBar>,
) -> bool {
// Base case 1: this is a file or a symbolic link.
// Use lstat to avoid race condition between check and use
match fs::symlink_metadata(path) {
Ok(metadata) if !metadata.is_dir() => {
return remove_file(path, options);
return remove_file(path, options, progress_bar);
}
Ok(_) => {}
Err(e) => {
Expand Down
Loading
Loading