diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index c1a28197fbca..6fa25d2debef 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 8e47084396f4..00aa4d42ebdc 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 3e0921e1429d..8ad76c10823f 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 eabb0549f73c..5f8f8130432d 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -974,6 +974,25 @@ c_group(OPTION *option, char ***argvp) 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 -- * diff --git a/usr.bin/find/main.c b/usr.bin/find/main.c index 4f7064b07c30..68972e41223d 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 f8745b24c2c4..b89420cbf0c0 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 },