mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
rm: rewrite to use fts
* remove.c: Don't include "unlinkdir.h"; no longer used. Do not include <setjmp.h> or "cycle-check.h". Likewise. Include "xfts.h". (dir_name, dir_len): Remove definitions. (CONSECUTIVE_READDIR_UNLINK_THRESHOLD): Likewise. (INODE_SORT_DIR_ENTRIES_THRESHOLD, NEED_REWIND, D_TYPE): Likewise. (struct dirstack_state, Dirstack_state): Likewise. (g_buf, g_n_allocated): Remove declarations. (hash_freer, hash_compare_strings, rm_malloc): Remove functions. (rm_free, push_dir, top_dir, pop_dir, right_justify): Likewise. (full_filename0, xfull_filename, full_filename_): Likewise. (AD_stack_height, AD_stack_top, AD_stack_pop, AD_stack_clear): Likewise. (obstack_init_minimal, ds_init, ds_clear, ds_free): Likewise. (AD_pop_and_chdir, AD_ensure_initialized, AD_mark_helper): Likewise. (AD_mark_as_unremovable, AD_mark_current_as_unremovable): Likewise. (AD_push_initial, AD_push, AD_push, AD_is_removable): Likewise. (write_protected_non_symlink): Change 3rd parameter from dirstack_state "ds" to full_name. (prompt): Adjust parameters. Now, state comes from FTS/FTSENT pair. Those replace fd_cwd and "ds". Remove "filename". Remove pdirent_type in favor of new "is_dir" parameter. Rename is_empty to is_empty_p. (DO_RMDIR, DO_UNLINK): Remove definitions. (remove_entry, fd_to_subdirp, compare_ino): Remove functions. (dirent_count, dirent_inode_sort_may_be_useful): Likewise. (preprocess_dir): Likewise. (fts_skip_tree, mark_ancestor_dirs, excise, rm_fts): New functions. (remove_cwd_entries, remove_dir, rm_1): Remove functions. (rm): Rewrite as a simple loop calling fts_read and dispatching each entry via rm_fts. * src/rm.c (main): Adapt to new signature of rm(). * bootstrap.conf (gnulib_modules): Remove unlinkdir, no longer used. * src/Makefile.am (sc_tight_scope): Also recognize an extern "enum" declaration. * tests/rm/empty-name: Adjust expected output to match new diagnostic. * NEWS (Improvements): Mention it.
This commit is contained in:
6
NEWS
6
NEWS
@@ -2,6 +2,12 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
|
||||
** Improvements
|
||||
|
||||
rm: rewrite to use gnulib's fts
|
||||
This makes rm -rf significantly faster (400-500%) in some pathological
|
||||
cases, and slightly slower (20%) in at least one pathological case.
|
||||
|
||||
|
||||
* Noteworthy changes in release 7.6 (2009-09-11) [stable]
|
||||
|
||||
|
||||
@@ -209,7 +209,6 @@ gnulib_modules="
|
||||
unicodeio
|
||||
unistd-safer
|
||||
unlink-busy
|
||||
unlinkdir
|
||||
unlocked-io
|
||||
update-copyright
|
||||
uptime
|
||||
|
||||
@@ -453,7 +453,7 @@ sc_tight_scope: $(bin_PROGRAMS)
|
||||
( printf 'main\nusage\n_.*\n'; \
|
||||
grep -h -A1 '^extern .*[^;]$$' $$src \
|
||||
| grep -vE '^(extern |--)' | sed 's/ .*//'; \
|
||||
perl -ne '/^extern \S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
|
||||
perl -ne '/^extern (?:enum )?\S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
|
||||
) | $(ASSORT) -u | sed 's/^/^/;s/$$/$$/' > $$t; \
|
||||
nm -e *.$(OBJEXT) \
|
||||
| sed -n 's/.* T //p' \
|
||||
|
||||
5
src/mv.c
5
src/mv.c
@@ -219,11 +219,14 @@ do_move (const char *source, const char *dest, const struct cp_options *x)
|
||||
{
|
||||
struct rm_options rm_options;
|
||||
enum RM_status status;
|
||||
char const *dir[2];
|
||||
|
||||
rm_option_init (&rm_options);
|
||||
rm_options.verbose = x->verbose;
|
||||
dir[0] = dir_to_remove;
|
||||
dir[1] = NULL;
|
||||
|
||||
status = rm (1, &dir_to_remove, &rm_options);
|
||||
status = rm ((void*) dir, &rm_options);
|
||||
assert (VALID_STATUS (status));
|
||||
if (status == RM_ERROR)
|
||||
ok = false;
|
||||
|
||||
1720
src/remove.c
1720
src/remove.c
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ struct rm_options
|
||||
/* If true, query the user about whether to remove each file. */
|
||||
enum rm_interactive interactive;
|
||||
|
||||
// FIXME: remove
|
||||
/* If true, do not traverse into (or remove) any directory that is
|
||||
on a file system (i.e., that has a different device number) other
|
||||
than that of the corresponding command line argument. Note that
|
||||
@@ -88,7 +89,6 @@ enum RM_status
|
||||
} \
|
||||
while (0)
|
||||
|
||||
enum RM_status rm (size_t n_files, char const *const *file,
|
||||
struct rm_options const *x);
|
||||
extern enum RM_status rm (char *const *file, struct rm_options const *x);
|
||||
|
||||
#endif
|
||||
|
||||
34
src/rm.c
34
src/rm.c
@@ -14,32 +14,9 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Rubin, David MacKenzie, and Richard Stallman.
|
||||
Reworked to use chdir and avoid recursion by Jim Meyering. */
|
||||
|
||||
/* Implementation overview:
|
||||
|
||||
In the `usual' case, RM saves no state for directories it is processing.
|
||||
When a removal fails (either due to an error or to an interactive `no'
|
||||
reply), the failure is noted (see description of `ht' in remove.c's
|
||||
remove_cwd_entries function) so that when/if the containing directory
|
||||
is reopened, RM doesn't try to remove the entry again.
|
||||
|
||||
RM may delete arbitrarily deep hierarchies -- even ones in which file
|
||||
names (from root to leaf) are longer than the system-imposed maximum.
|
||||
It does this by using chdir to change to each directory in turn before
|
||||
removing the entries in that directory.
|
||||
|
||||
RM detects directory cycles lazily. See lib/cycle-check.c.
|
||||
|
||||
RM is careful to avoid forming full file names whenever possible.
|
||||
A full file name is formed only when it is about to be used -- e.g.
|
||||
in a diagnostic or in an interactive-mode prompt.
|
||||
|
||||
RM minimizes the number of lstat system calls it makes. On systems
|
||||
that have valid d_type data in directory entries, RM makes only one
|
||||
lstat call per command line argument -- regardless of the depth of
|
||||
the hierarchy. */
|
||||
/* Initially written by Paul Rubin, David MacKenzie, and Richard Stallman.
|
||||
Reworked to use chdir and avoid recursion, and later, rewritten
|
||||
once again, to use fts, by Jim Meyering. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
@@ -358,7 +335,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
size_t n_files = argc - optind;
|
||||
char const *const *file = (char const *const *) argv + optind;
|
||||
char **file = argv + optind;
|
||||
|
||||
if (prompt_once && (x.recursive || 3 < n_files))
|
||||
{
|
||||
@@ -370,7 +347,8 @@ main (int argc, char **argv)
|
||||
if (!yesno ())
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
enum RM_status status = rm (n_files, file, &x);
|
||||
|
||||
enum RM_status status = rm (file, &x);
|
||||
assert (VALID_STATUS (status));
|
||||
exit (status == RM_ERROR ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ my @Tests =
|
||||
# test-name options input expected-output
|
||||
#
|
||||
['empty-name-1', "''", {EXIT => 1},
|
||||
{ERR => "$prog: cannot remove `': No such file or directory\n"}],
|
||||
{ERR => "$prog: invalid argument: `'\n"}],
|
||||
);
|
||||
|
||||
my $save_temps = $ENV{SAVE_TEMPS};
|
||||
|
||||
Reference in New Issue
Block a user