90 lines
3.1 KiB
Diff
90 lines
3.1 KiB
Diff
From 0afb2efada7e435ae18ef7d3db0758464189f44f Mon Sep 17 00:00:00 2001
|
|
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
|
Date: Tue, 30 Jan 2018 23:30:09 +0100
|
|
Subject: [PATCH 159/224] find: make -delete honour the -ignore_readdir_race
|
|
option
|
|
|
|
* find/pred.c (pred_delete): Return true when the -ignore_readdir_race
|
|
option is active and unlinkat() came back with ENOENT.
|
|
* doc/find.texi (Option -ignore_readdir_race): Document the change.
|
|
(Action -delete): Likewise.
|
|
* find/find.1: Likewise.
|
|
* NEWS (Bug Fixes): Mention the fix.
|
|
|
|
For now, it seems a bit hard to add a proper test for this,
|
|
so the following shell snippet demonstrates the race:
|
|
|
|
$ seq 10 | xargs touch
|
|
$ env time -f 'find exit status: %x\nfind time: %e' \
|
|
find -ignore_readdir_race -type f \
|
|
-delete \
|
|
-exec sh -c 'sleep $(basename {})' \; \
|
|
-printf 'find deleted: %p\n' \
|
|
& \
|
|
sleep 20; \
|
|
seq 10 | xargs rm -fv; \
|
|
wait $!
|
|
|
|
Reported by Alexander Golubev in
|
|
https://savannah.gnu.org/bugs/?52981
|
|
---
|
|
NEWS | 4 ++++
|
|
doc/find.texi | 15 ++++++++++++++-
|
|
find/find.1 | 22 ++++++++++++++++++++++
|
|
find/pred.c | 6 ++++++
|
|
4 files changed, 46 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/doc/find.texi b/doc/find.texi
|
|
index 3580be75..0089193e 100644
|
|
--- a/doc/find.texi
|
|
+++ b/doc/find.texi
|
|
@@ -1424,7 +1424,15 @@ gives a significant increase in search speed.
|
|
If a file disappears after its name has been read from a directory but
|
|
before @code{find} gets around to examining the file with @code{stat},
|
|
don't issue an error message. If you don't specify this option, an
|
|
-error message will be issued. This option can be useful in system
|
|
+error message will be issued.
|
|
+
|
|
+Furthermore, @code{find} with the @samp{-ignore_readdir_race} option
|
|
+will ignore errors of the @samp{-delete} action in the case the file
|
|
+has disappeared since the parent directory was read: it will not output
|
|
+an error diagnostic, and the return code of the @samp{-delete} action
|
|
+will be true.
|
|
+
|
|
+This option can be useful in system
|
|
scripts (cron scripts, for example) that examine areas of the
|
|
filesystem that change frequently (mail queues, temporary directories,
|
|
and so forth), because this scenario is common for those sorts of
|
|
@@ -2787,6 +2795,11 @@ explicitly.
|
|
|
|
If @samp{-delete} fails, @code{find}'s exit status will be nonzero
|
|
(when it eventually exits).
|
|
+
|
|
+Together with the @samp{-ignore_readdir_race} option, @code{find} will
|
|
+ignore errors of the @samp{-delete} action in the case the file has disappeared
|
|
+since the parent directory was read: it will not output an error diagnostic, and
|
|
+the return code of the @samp{-delete} action will be true.
|
|
@end deffn
|
|
|
|
@node Adding Tests
|
|
diff --git a/find/pred.c b/find/pred.c
|
|
index 7e2a7bde..af3bacbc 100644
|
|
--- a/find/pred.c
|
|
+++ b/find/pred.c
|
|
@@ -316,6 +316,12 @@ pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred
|
|
}
|
|
else
|
|
{
|
|
+ if (ENOENT == errno && options.ignore_readdir_race)
|
|
+ {
|
|
+ /* Ignore unlink() error for vanished files. */
|
|
+ errno = 0;
|
|
+ return true;
|
|
+ }
|
|
if (EISDIR == errno)
|
|
{
|
|
if ((flags & AT_REMOVEDIR) == 0)
|
|
--
|
|
2.19.1
|
|
|