Re: rm -iR

RVP <[email protected]> Wed, 4 Feb 2026 05:48:24 +0000 (UTC)
Newsgroups gmane.os.netbsd.devel.userlevel
Message-ID <[email protected]>
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