summaryrefslogtreecommitdiffstats
path: root/usr.bin/find
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2012-07-25 21:59:10 +0000
committerjilles <jilles@FreeBSD.org>2012-07-25 21:59:10 +0000
commit06d71385564614c8f19a2407e234e9f2ea142750 (patch)
tree9e7e20bd4ba232a68faf9db468bc5fe8597aae6e /usr.bin/find
parent9a57e402a6d1d149388a8af3ffce132e6ea9d0dc (diff)
downloadFreeBSD-src-06d71385564614c8f19a2407e234e9f2ea142750.zip
FreeBSD-src-06d71385564614c8f19a2407e234e9f2ea142750.tar.gz
find: Implement real -ignore_readdir_race.
If -ignore_readdir_race is present, [ENOENT] errors caused by deleting a file after find has read its name from a directory are ignored. Formerly, -ignore_readdir_race did nothing. PR: bin/169723 Submitted by: Valery Khromov and Andrey Ignatov
Diffstat (limited to 'usr.bin/find')
-rw-r--r--usr.bin/find/extern.h4
-rw-r--r--usr.bin/find/find.110
-rw-r--r--usr.bin/find/find.c8
-rw-r--r--usr.bin/find/function.c19
-rw-r--r--usr.bin/find/main.c1
-rw-r--r--usr.bin/find/option.c4
6 files changed, 38 insertions, 8 deletions
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index c1a2819..6fa25d2 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -58,6 +58,7 @@ creat_f c_flags;
creat_f c_follow;
creat_f c_fstype;
creat_f c_group;
+creat_f c_ignore_readdir_race;
creat_f c_inum;
creat_f c_links;
creat_f c_ls;
@@ -111,7 +112,8 @@ exec_f f_size;
exec_f f_type;
exec_f f_user;
-extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs;
+extern int ftsoptions, ignore_readdir_race, isdeprecated, isdepth, isoutput;
+extern int issort, isxargs;
extern int mindepth, maxdepth;
extern int regexp_flags;
extern time_t now;
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 8e47084..00aa4d4 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -31,7 +31,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd June 13, 2012
+.Dd July 25, 2012
.Dt FIND 1
.Os
.Sh NAME
@@ -470,7 +470,9 @@ is numeric and there is no such group name, then
.Ar gname
is treated as a group ID.
.It Ic -ignore_readdir_race
-This option is for GNU find compatibility and is ignored.
+Ignore errors because a file or a directory is deleted
+after reading the name from a directory.
+This option does not affect errors occurring on starting points.
.It Ic -ilname Ar pattern
Like
.Ic -lname ,
@@ -618,7 +620,9 @@ is equivalent to
.It Ic -nogroup
True if the file belongs to an unknown group.
.It Ic -noignore_readdir_race
-This option is for GNU find compatibility and is ignored.
+Turn off the effect of
+.Ic -ignore_readdir_race .
+This is default behaviour.
.It Ic -noleaf
This option is for GNU find compatibility.
In GNU find it disables an optimization not relevant to
diff --git a/usr.bin/find/find.c b/usr.bin/find/find.c
index 3e0921e..8ad76c1 100644
--- a/usr.bin/find/find.c
+++ b/usr.bin/find/find.c
@@ -197,8 +197,12 @@ find_execute(PLAN *plan, char *paths[])
continue;
break;
case FTS_DNR:
- case FTS_ERR:
case FTS_NS:
+ if (ignore_readdir_race &&
+ entry->fts_errno == ENOENT && entry->fts_level > 0)
+ continue;
+ /* FALLTHROUGH */
+ case FTS_ERR:
(void)fflush(stdout);
warnx("%s: %s",
entry->fts_path, strerror(entry->fts_errno));
@@ -228,7 +232,7 @@ find_execute(PLAN *plan, char *paths[])
for (p = plan; p && (p->execute)(p, entry); p = p->next);
}
finish_execplus();
- if (errno)
+ if (errno && (!ignore_readdir_race || errno != ENOENT))
err(1, "fts_read");
return (rval);
}
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index eabb054..5f8f813 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -975,6 +975,25 @@ c_group(OPTION *option, char ***argvp)
}
/*
+ * -ignore_readdir_race functions --
+ *
+ * Always true. Ignore errors which occur if a file or a directory
+ * in a starting point gets deleted between reading the name and calling
+ * stat on it while find is traversing the starting point.
+ */
+
+PLAN *
+c_ignore_readdir_race(OPTION *option, char ***argvp __unused)
+{
+ if (strcmp(option->name, "-ignore_readdir_race") == 0)
+ ignore_readdir_race = 1;
+ else
+ ignore_readdir_race = 0;
+
+ return palloc(option);
+}
+
+/*
* -inum n functions --
*
* True if the file has inode # n.
diff --git a/usr.bin/find/main.c b/usr.bin/find/main.c
index 4f7064b..68972e4 100644
--- a/usr.bin/find/main.c
+++ b/usr.bin/find/main.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
time_t now; /* time find was run */
int dotfd; /* starting directory */
int ftsoptions; /* options for the ftsopen(3) call */
+int ignore_readdir_race = 0; /* ignore readdir race */
int isdeprecated; /* using deprecated syntax */
int isdepth; /* do directories on post-order visit */
int isoutput; /* user specified output operator */
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index f8745b2..b89420c 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -88,7 +88,7 @@ static OPTION const options[] = {
{ "-fstype", c_fstype, f_fstype, 0 },
{ "-gid", c_group, f_group, 0 },
{ "-group", c_group, f_group, 0 },
- { "-ignore_readdir_race",c_simple, f_always_true,0 },
+ { "-ignore_readdir_race",c_ignore_readdir_race, f_always_true,0 },
{ "-ilname", c_name, f_name, F_LINK | F_IGNCASE },
{ "-iname", c_name, f_name, F_IGNCASE },
{ "-inum", c_inum, f_inum, 0 },
@@ -127,7 +127,7 @@ static OPTION const options[] = {
{ "-newermm", c_newer, f_newer, 0 },
{ "-newermt", c_newer, f_newer, F_TIME2_T },
{ "-nogroup", c_nogroup, f_nogroup, 0 },
- { "-noignore_readdir_race",c_simple, f_always_true,0 },
+ { "-noignore_readdir_race",c_ignore_readdir_race, f_always_true,0 },
{ "-noleaf", c_simple, f_always_true, 0 },
{ "-not", c_simple, f_not, 0 },
{ "-nouser", c_nouser, f_nouser, 0 },
OpenPOWER on IntegriCloud