tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: rm -iR



On Tue, 3 Feb 2026, Jan Schaumann wrote:

Date: Tue, 3 Feb 2026 14:30:46 -0500
From: Jan Schaumann <jschauma%netmeister.org@localhost>
To: tech-userlevel%netbsd.org@localhost
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


Home | Main Index | Thread Index | Old Index