Package: coreutils;
Reported by: Linda Walsh <coreutils <at> tlinx.org>
Date: Tue, 19 Nov 2013 11:58:02 UTC
Severity: normal
Tags: notabug, patch
Merged with 15943
Done: Assaf Gordon <assafgordon <at> gmail.com>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Bernhard Voelker <mail <at> bernhard-voelker.de> To: Eric Blake <eblake <at> redhat.com> Cc: 15926 <at> debbugs.gnu.org, Bob Proulx <bob <at> proulx.com> Subject: bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call Date: Thu, 21 Nov 2013 17:18:35 +0100
On 11/21/2013 04:06 PM, Eric Blake wrote: > Hard to say that it is considerable bloat without seeing a patch; we > already know when the top-level arguments are directories thanks to 'rm -d'. Here's a draft - not tested more than this: $ mkdir -p /tmp/dir /tmp/dir/sub $ touch /tmp/dir/file /tmp/dir/sub/other $ src/rm -rv --child /tmp/dir removed ‘/tmp/dir/file’ removed ‘/tmp/dir/sub/other’ removed directory: ‘/tmp/dir/sub’ src/rm: skipping ‘/tmp/dir’, due to --children-only $ src/rm -rv --child /tmp/dir src/rm: skipping ‘/tmp/dir’, due to --children-only $ src/rm -rv --child /tmp/dir/. src/rm: skipping ‘/tmp/dir/.’, due to --children-only Have a nice day, Berny From 03d58cc281c6155d50be9b770bbac7bf73cdaf92 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker <mail <at> bernhard-voelker.de> Date: Thu, 21 Nov 2013 17:11:27 +0100 Subject: [PATCH] rm: add --children-only option FIXME --- src/mv.c | 1 + src/remove.c | 29 ++++++++++++++++++++++++----- src/remove.h | 4 ++++ src/rm.c | 9 +++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/mv.c b/src/mv.c index 1cfcd82..36e70a4 100644 --- a/src/mv.c +++ b/src/mv.c @@ -74,6 +74,7 @@ rm_option_init (struct rm_options *x) { x->ignore_missing_files = false; x->remove_empty_directories = true; + x->children_only = false; x->recursive = true; x->one_file_system = false; diff --git a/src/remove.c b/src/remove.c index 3d386cf..eb05cb4 100644 --- a/src/remove.c +++ b/src/remove.c @@ -439,8 +439,10 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) { /* POSIX says: If the basename of a command line argument is "." or "..", - diagnose it and do nothing more with that argument. */ - if (dot_or_dotdot (last_component (ent->fts_accpath))) + diagnose it and do nothing more with that argument. + FIXME: mention --children-only. */ + if (! x->children_only + && dot_or_dotdot (last_component (ent->fts_accpath))) { error (0, 0, _("refusing to remove %s or %s directory: skipping %s"), @@ -468,9 +470,17 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) if (s == RM_OK && is_empty_directory == T_YES) { - /* When we know (from prompt when in interactive mode) - that this is an empty directory, don't prompt twice. */ - s = excise (fts, ent, x, true); + if (FTS_ROOTLEVEL == ent->fts_level && x->children_only) + { + error (0, 0, _("skipping %s, due to --children-only"), + quote (ent->fts_path)); + } + else + { + /* When we know (from prompt when in interactive mode) + that this is an empty directory, don't prompt twice. */ + s = excise (fts, ent, x, true); + } fts_skip_tree (fts, ent); } @@ -492,6 +502,15 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) case FTS_NSOK: /* e.g., dangling symlink */ case FTS_DEFAULT: /* none of the above */ { + if (ent->fts_info == FTS_DP + && x->children_only + && FTS_ROOTLEVEL == ent->fts_level) + { + mark_ancestor_dirs (ent); + error (0, 0, _("skipping %s, due to --children-only"), + quote (ent->fts_path)); + return RM_OK; + } /* With --one-file-system, do not attempt to remove a mount point. fts' FTS_XDEV ensures that we don't process any entries under the mount point. */ diff --git a/src/remove.h b/src/remove.h index 9ac54d4..248a470 100644 --- a/src/remove.h +++ b/src/remove.h @@ -52,6 +52,10 @@ struct rm_options /* If true, remove empty directories. */ bool remove_empty_directories; + /* If true (and the -r option is also specified), remove all children + of directory arguments, yet retaining the directory itself. */ + bool children_only; + /* Pointer to the device and inode numbers of '/', when --recursive and preserving '/'. Otherwise NULL. */ struct dev_ino *root_dev_ino; diff --git a/src/rm.c b/src/rm.c index 7a51eef..0634855 100644 --- a/src/rm.c +++ b/src/rm.c @@ -51,6 +51,7 @@ enum ONE_FILE_SYSTEM, NO_PRESERVE_ROOT, PRESERVE_ROOT, + CHILDREN_ONLY, PRESUME_INPUT_TTY_OPTION }; @@ -78,6 +79,7 @@ static struct option const long_opts[] = {"recursive", no_argument, NULL, 'r'}, {"dir", no_argument, NULL, 'd'}, + {"children-only", no_argument, NULL, CHILDREN_ONLY}, {"verbose", no_argument, NULL, 'v'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -156,6 +158,8 @@ Remove (unlink) the FILE(s).\n\ --preserve-root do not remove '/' (default)\n\ -r, -R, --recursive remove directories and their contents recursively\n\ -d, --dir remove empty directories\n\ + --children-only remove only children, yet retaining the given\n\ + directory arguments\n\ -v, --verbose explain what is being done\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); @@ -192,6 +196,7 @@ rm_option_init (struct rm_options *x) x->interactive = RMI_SOMETIMES; x->one_file_system = false; x->remove_empty_directories = false; + x->children_only = false; x->recursive = false; x->root_dev_ino = NULL; x->stdin_tty = isatty (STDIN_FILENO); @@ -296,6 +301,10 @@ main (int argc, char **argv) preserve_root = true; break; + case CHILDREN_ONLY: + x.children_only = true; + break; + case PRESUME_INPUT_TTY_OPTION: x.stdin_tty = true; break; -- 1.8.4.2
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.