On Tue, 3 Feb 2026, Jan Schaumann wrote:

Date: Tue, 3 Feb 2026 14:30:46 -0500
From: Jan Schaumann <[email protected]>
To: [email protected]
Subject: rm -iR

Hello,

rm(1) currently says for the '-R' flag:

"If the -i option is specified, the user is prompted
for confirmation before each directory's contents are
processed (as well as before the attempt is made to
remove the directory)."

But it's actually a bit misleading and only prompts
for _removal_ of a directory, not for processing the
contents:

$ mkdir -p dir/subdir/subsub dir/subdir2
$ touch dir/file dir/subdir/file dir/subdir/subsub/file dir/subdir2/file
$ rm -ir dir
remove 'dir'? n
$


This do?

---START patch---
--- rm.c.orig   2025-05-12 23:36:20.000000000 +0000
+++ rm.c        2026-02-04 05:38:44.024425907 +0000
@@ -64,7 +64,7 @@
 static int xflag;
 static sig_atomic_t pinfo;

-static int     check(char *, char *, struct stat *);
+static int     check(char *, char *, struct stat *, char *);
 static void    checkdot(char **);
 static void    progress(int);
 static void    rm_file(char **);
@@ -214,7 +214,7 @@
                case FTS_D:
                        /* Pre-order: give user chance to skip. */
                        if (!fflag && !check(p->fts_path, p->fts_accpath,
-                           p->fts_statp)) {
+                           p->fts_statp, "enter")) {
                                (void)fts_set(fts, p, FTS_SKIP);
                                p->fts_number = SKIPPED;
                        }
@@ -226,7 +226,7 @@
                        break;
                default:
                        if (!fflag &&
-                           !check(p->fts_path, p->fts_accpath, p->fts_statp))
+                           !check(p->fts_path, p->fts_accpath, p->fts_statp, 
"remove"))
                                continue;
                }

@@ -239,6 +239,8 @@
                switch (p->fts_info) {
                case FTS_DP:
                case FTS_DNR:
+                       if (!check(p->fts_path, p->fts_accpath, p->fts_statp, 
"remove"))
+                               continue;
                        rval = rmdir(p->fts_accpath);
                        if (rval != 0 && fflag && errno == ENOENT)
                                continue;
@@ -307,7 +309,7 @@
                        eval = 1;
                        continue;
                }
-               if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
+               if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb, 
"remove"))
                        continue;
                if (S_ISWHT(sb.st_mode))
                        rval = undelete(f);
@@ -515,14 +517,14 @@
 }

 static int
-check(char *path, char *name, struct stat *sp)
+check(char *path, char *name, struct stat *sp, char* dowhat)
 {
        int ch, first;
        char modep[15];

        /* Check -i first. */
        if (iflag)
-               (void)fprintf(stderr, "remove '%s'? ", path);
+               (void)fprintf(stderr, "%s '%s'? ", dowhat, path);
        else {
                /*
                 * If it's not a symbolic link and it's unwritable and we're
---END patch---

-RVP

Reply via email to