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
This commit is contained in:
Jilles Tjoelker 2012-07-25 21:59:10 +00:00
parent 7f14a4d6b1
commit 40072dc2b7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238780
6 changed files with 38 additions and 8 deletions

View File

@ -58,6 +58,7 @@ creat_f c_flags;
creat_f c_follow; creat_f c_follow;
creat_f c_fstype; creat_f c_fstype;
creat_f c_group; creat_f c_group;
creat_f c_ignore_readdir_race;
creat_f c_inum; creat_f c_inum;
creat_f c_links; creat_f c_links;
creat_f c_ls; creat_f c_ls;
@ -111,7 +112,8 @@ exec_f f_size;
exec_f f_type; exec_f f_type;
exec_f f_user; 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 mindepth, maxdepth;
extern int regexp_flags; extern int regexp_flags;
extern time_t now; extern time_t now;

View File

@ -31,7 +31,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95 .\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 13, 2012 .Dd July 25, 2012
.Dt FIND 1 .Dt FIND 1
.Os .Os
.Sh NAME .Sh NAME
@ -470,7 +470,9 @@ is numeric and there is no such group name, then
.Ar gname .Ar gname
is treated as a group ID. is treated as a group ID.
.It Ic -ignore_readdir_race .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 .It Ic -ilname Ar pattern
Like Like
.Ic -lname , .Ic -lname ,
@ -618,7 +620,9 @@ is equivalent to
.It Ic -nogroup .It Ic -nogroup
True if the file belongs to an unknown group. True if the file belongs to an unknown group.
.It Ic -noignore_readdir_race .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 .It Ic -noleaf
This option is for GNU find compatibility. This option is for GNU find compatibility.
In GNU find it disables an optimization not relevant to In GNU find it disables an optimization not relevant to

View File

@ -197,8 +197,12 @@ find_execute(PLAN *plan, char *paths[])
continue; continue;
break; break;
case FTS_DNR: case FTS_DNR:
case FTS_ERR:
case FTS_NS: case FTS_NS:
if (ignore_readdir_race &&
entry->fts_errno == ENOENT && entry->fts_level > 0)
continue;
/* FALLTHROUGH */
case FTS_ERR:
(void)fflush(stdout); (void)fflush(stdout);
warnx("%s: %s", warnx("%s: %s",
entry->fts_path, strerror(entry->fts_errno)); 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); for (p = plan; p && (p->execute)(p, entry); p = p->next);
} }
finish_execplus(); finish_execplus();
if (errno) if (errno && (!ignore_readdir_race || errno != ENOENT))
err(1, "fts_read"); err(1, "fts_read");
return (rval); return (rval);
} }

View File

@ -974,6 +974,25 @@ c_group(OPTION *option, char ***argvp)
return new; return new;
} }
/*
* -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 -- * -inum n functions --
* *

View File

@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
time_t now; /* time find was run */ time_t now; /* time find was run */
int dotfd; /* starting directory */ int dotfd; /* starting directory */
int ftsoptions; /* options for the ftsopen(3) call */ int ftsoptions; /* options for the ftsopen(3) call */
int ignore_readdir_race = 0; /* ignore readdir race */
int isdeprecated; /* using deprecated syntax */ int isdeprecated; /* using deprecated syntax */
int isdepth; /* do directories on post-order visit */ int isdepth; /* do directories on post-order visit */
int isoutput; /* user specified output operator */ int isoutput; /* user specified output operator */

View File

@ -88,7 +88,7 @@ static OPTION const options[] = {
{ "-fstype", c_fstype, f_fstype, 0 }, { "-fstype", c_fstype, f_fstype, 0 },
{ "-gid", c_group, f_group, 0 }, { "-gid", c_group, f_group, 0 },
{ "-group", 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 }, { "-ilname", c_name, f_name, F_LINK | F_IGNCASE },
{ "-iname", c_name, f_name, F_IGNCASE }, { "-iname", c_name, f_name, F_IGNCASE },
{ "-inum", c_inum, f_inum, 0 }, { "-inum", c_inum, f_inum, 0 },
@ -127,7 +127,7 @@ static OPTION const options[] = {
{ "-newermm", c_newer, f_newer, 0 }, { "-newermm", c_newer, f_newer, 0 },
{ "-newermt", c_newer, f_newer, F_TIME2_T }, { "-newermt", c_newer, f_newer, F_TIME2_T },
{ "-nogroup", c_nogroup, f_nogroup, 0 }, { "-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 }, { "-noleaf", c_simple, f_always_true, 0 },
{ "-not", c_simple, f_not, 0 }, { "-not", c_simple, f_not, 0 },
{ "-nouser", c_nouser, f_nouser, 0 }, { "-nouser", c_nouser, f_nouser, 0 },