summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-09-03 15:15:09 +0200
committerJim Meyering <meyering@redhat.com>2009-09-11 14:08:58 +0200
commit722287e443c93e04e724e2812857a395cfab0b60 (patch)
tree6513b8c652ab59cd12c79fe722930a3ce5f73978 /src
parent9966c92dd4851db611ad88fc1eb68b01fffcaea3 (diff)
downloadcoreutils-722287e443c93e04e724e2812857a395cfab0b60.tar.xz
rm: improve efficiency of rm -r (without -f) from O(N^2) to O(N)
where N is the depth of the deepest hierarchy rm is processing. * src/remove.c (write_protected_non_symlink): Use faccessat to avoid O(N)-per-entry cost of calling euidaccess. * m4/jm-macros.m4 (coreutils_MACROS): Check for faccessat. * NEWS (Improvements): Mention it.
Diffstat (limited to 'src')
-rw-r--r--src/remove.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/remove.c b/src/remove.c
index 32f67a181..2db385909 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -172,6 +172,13 @@ write_protected_non_symlink (int fd_cwd,
mess up with long file names). */
{
+ /* Use faccessat if possible, so as to avoid the expense
+ of processing an N-component name. */
+#if HAVE_FACCESSAT && AT_EACCESS
+ if (faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0)
+ return 0;
+#endif
+
/* This implements #5: */
size_t file_name_len = strlen (full_name);