From rdna@rdna.ru  Sun Jul  8 22:41:51 2012
Return-Path: <rdna@rdna.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 68DFD1065672
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  8 Jul 2012 22:41:51 +0000 (UTC)
	(envelope-from rdna@rdna.ru)
Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com [209.85.217.182])
	by mx1.freebsd.org (Postfix) with ESMTP id DC8128FC0A
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  8 Jul 2012 22:41:50 +0000 (UTC)
Received: by lbon10 with SMTP id n10so19039822lbo.13
        for <FreeBSD-gnats-submit@freebsd.org>; Sun, 08 Jul 2012 15:41:49 -0700 (PDT)
Received: by 10.112.48.39 with SMTP id i7mr17575383lbn.31.1341787309677;
        Sun, 08 Jul 2012 15:41:49 -0700 (PDT)
Received: from localhost (ip-46-73-208-248.bb.netbynet.ru. [46.73.208.248])
        by mx.google.com with ESMTPS id j3sm16252116lbh.0.2012.07.08.15.41.47
        (version=TLSv1/SSLv3 cipher=OTHER);
        Sun, 08 Jul 2012 15:41:48 -0700 (PDT)
Message-Id: <4ffa0cac.631d700a.648c.ffffb394@mx.google.com>
Date: Sun, 08 Jul 2012 15:41:48 -0700 (PDT)
From: Andrey Ignatov <rdna@rdna.ru>
Reply-To: Andrey Ignatov <rdna@rdna.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Valery Khromov <qwerty@yandex-team.ru>
Subject: [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         169723
>Category:       bin
>Synopsis:       [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jilles
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 08 22:50:06 UTC 2012
>Closed-Date:    Sun Apr 20 16:58:15 UTC 2014
>Last-Modified:  Sun Apr 20 16:58:15 UTC 2014
>Originator:     Andrey Ignatov
>Release:        FreeBSD 10.0-CURRENT amd64
>Organization:
Yandex
>Environment:
System: FreeBSD rdna-s761.yandex.ru 10.0-CURRENT FreeBSD 10.0-CURRENT #0 r228743M: Sat Dec 31 15:15:00 MSK 2011 root@rdna.yandex.ru:/usr/obj/usr/src/sys/RDNA amd64

It seems that the problem appears in find(1) on many versions of FreeBSD
(8-10 at least).

>Description:
find(1) exits with non-zero return code if any file in a directory is deleted
while find(1) is traversing the directory, even though the file is completely
out of find's expression.

For example, we can run:
% find /path/to/some/dir/ -type f -a ! -name '*some_mask*'

Then while find is traversing the directory /path/to/some/dir/ we remove some
files which is out of the expression:
% rm /path/to/some/dir/*some_mask*

(Note: I use "!" in the expression)

After this find finishes with the result like this:
find: /path/to/some/dir/some_mask: No such file or directory
% echo $?
1

>How-To-Repeat:
It's easy to reproduce the problem by using attached Makefile. Just run `make all'.

>Fix:
The patch is in attached freebsd-find-ENOENT-and-removed-files.patch file.

Reported and patched by: Valery Khromov <qwerty@yandex-team.ru>

--- Makefile begins here ---
D:=testdir
FIND?=find

all: prepare
	$(MAKE) -j16 mkfiles rmfiles find

mkfiles:
	dd if=/dev/urandom | hexdump -e '"" 8/1 "%02x" "\n"' | while read i ; do touch "$(D)/$$i"; done

rmfiles:
	while :; do rm -f $(D)/*; sleep 1; done

find:
	while :; do $(FIND) $(D)/ -type f -name '*NAME*' || echo FAILED; done

prepare:
	rm -rf $(D)
	mkdir -p $(D)
--- Makefile ends here ---

--- freebsd-find-ENOENT-and-removed-files.patch begins here ---
Index: /usr/src/usr.bin/find/find.c
===================================================================
--- /usr/src/usr.bin/find/find.c	(revision 228743)
+++ /usr/src/usr.bin/find/find.c	(working copy)
@@ -199,6 +199,8 @@
 		case FTS_DNR:
 		case FTS_ERR:
 		case FTS_NS:
+			if (entry->fts_errno == ENOENT)
+				continue;
 			(void)fflush(stdout);
 			warnx("%s: %s",
 			    entry->fts_path, strerror(entry->fts_errno));
--- freebsd-find-ENOENT-and-removed-files.patch ends here ---


>Release-Note:
>Audit-Trail:

From: Jilles Tjoelker <jilles@stack.nl>
To: bug-followup@FreeBSD.org, rdna@rdna.ru
Cc:  
Subject: Re: bin/169723: [patch] find(1) exits with non-zero return code if
 any file in a directory is deleted while find(1) is traversing the directory
Date: Sun, 15 Jul 2012 17:43:53 +0200

 In PR 169723, you wrote:
 > [find(1) prints an error message if a file is deleted between readdir
 > and stat or opendir]
 
 This patch appears to match the description of
 -ignore_readdir_race in the documentation of GNU find. Perhaps it is
 appropriate to suppress these error messages only if
 -ignore_readdir_race is given (and -noignore_readdir_race is not given
 afterwards).
 
 Furthermore, it only seems appropriate to me to suppress the error for
 FTS_DNR and FTS_NS. FTS_ERR covers things like inability to open "."
 which should never fail (so if they do, find(1) should tell the user
 about it).
 
 -- 
 Jilles Tjoelker

From: Andrey Ignatov <rdna@rdna.ru>
To: Jilles Tjoelker <jilles@stack.nl>
Cc: bug-followup@FreeBSD.org, Valery Khromov <qwerty@yandex-team.ru>
Subject: Re: bin/169723: [patch] find(1) exits with non-zero return code if
 any file in a directory is deleted while find(1) is traversing the directory
Date: Tue, 17 Jul 2012 21:53:16 +0400

 --LQksG6bCIzRHxTLp
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
 Hi, Jilles!
 
 Thank you for the information!
 
 We've taken into account all your points and impletemted both options
 (-ignore_readdir_race and -noignore_readdir_race). The default behaviour
 is -noignore_readdir_race.
 The patch is attached as well as the new Makefile to test it.
 
 Jilles Tjoelker <jilles@stack.nl> [2012-07-15 19:43]:
 > In PR 169723, you wrote:
 > > [find(1) prints an error message if a file is deleted between readdir
 > > and stat or opendir]
 > 
 > This patch appears to match the description of
 > -ignore_readdir_race in the documentation of GNU find. Perhaps it is
 > appropriate to suppress these error messages only if
 > -ignore_readdir_race is given (and -noignore_readdir_race is not given
 > afterwards).
 > 
 > Furthermore, it only seems appropriate to me to suppress the error for
 > FTS_DNR and FTS_NS. FTS_ERR covers things like inability to open "."
 > which should never fail (so if they do, find(1) should tell the user
 > about it).
 > 
 > -- 
 > Jilles Tjoelker
 
 -- 
 Andrey Ignatov
 
 --LQksG6bCIzRHxTLp
 Content-Type: text/x-diff; charset=koi8-r
 Content-Disposition: attachment; filename="freebsd9-ignore_readdir_race_v4.patch"
 
 Index: usr.bin/find/find.1
 ===================================================================
 --- usr.bin/find/find.1	(revision 238532)
 +++ usr.bin/find/find.1	(working copy)
 @@ -467,7 +467,10 @@
  .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 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.
 +This option doesn't affect errors occuring on starting points.
  .It Ic -ilname Ar pattern
  Like
  .Ic -lname ,
 @@ -615,7 +618,9 @@
  .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 
 Index: usr.bin/find/find.c
 ===================================================================
 --- usr.bin/find/find.c	(revision 238532)
 +++ usr.bin/find/find.c	(working copy)
 @@ -197,8 +197,11 @@
  				continue;
  			break;
  		case FTS_DNR:
 +		case FTS_NS:
 +			if (ignore_readdir_race &&
 +			    entry->fts_errno == ENOENT && entry->fts_level)
 +				continue;
  		case FTS_ERR:
 -		case FTS_NS:
  			(void)fflush(stdout);
  			warnx("%s: %s",
  			    entry->fts_path, strerror(entry->fts_errno));
 @@ -228,7 +231,7 @@
  		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);
  }
 Index: usr.bin/find/main.c
 ===================================================================
 --- usr.bin/find/main.c	(revision 238532)
 +++ usr.bin/find/main.c	(working copy)
 @@ -64,6 +64,7 @@
  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 */
 Index: usr.bin/find/function.c
 ===================================================================
 --- usr.bin/find/function.c	(revision 238532)
 +++ usr.bin/find/function.c	(working copy)
 @@ -975,6 +975,25 @@
  }
  
  /*
 + * -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.
 Index: usr.bin/find/option.c
 ===================================================================
 --- usr.bin/find/option.c	(revision 238532)
 +++ usr.bin/find/option.c	(working copy)
 @@ -88,7 +88,7 @@
  	{ "-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 @@
  	{ "-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 },
 Index: usr.bin/find/extern.h
 ===================================================================
 --- usr.bin/find/extern.h	(revision 238532)
 +++ usr.bin/find/extern.h	(working copy)
 @@ -58,6 +58,7 @@
  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_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;
 
 --LQksG6bCIzRHxTLp
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: attachment; filename=Makefile
 
 D:=testdir
 FIND?=find
 
 all: prepare
 	$(MAKE) -j16 mkfiles mkdirs rmfiles find
 
 mkfiles:
 	dd if=/dev/urandom | hexdump -e '"" 8/1 "%02x" "\n"' | while read i ; do touch "$(D)/$$i"; done
 
 mkdirs:
 	dd if=/dev/urandom | hexdump -e '"" 8/1 "%02x" "\n"' | while read i ; do mkdir "$(D)/$$i"; done
 
 rmfiles:
 	while :; do rm -rf $(D)/*; sleep 1; done
 
 find:
 	while :; do $(FIND) $(D)/ $(FINDFLAGS) -type f -name '*NAME*' || echo FAILED; done
 
 prepare:
 	rm -rf $(D)
 	mkdir -p $(D)
 
 --LQksG6bCIzRHxTLp--
Responsible-Changed-From-To: freebsd-bugs->jilles 
Responsible-Changed-By: jilles 
Responsible-Changed-When: Fri Jul 20 10:12:44 UTC 2012 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169723 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/169723: commit references a PR
Date: Wed, 25 Jul 2012 21:59:22 +0000 (UTC)

 Author: jilles
 Date: Wed Jul 25 21:59:10 2012
 New Revision: 238780
 URL: http://svn.freebsd.org/changeset/base/238780
 
 Log:
   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
 
 Modified:
   head/usr.bin/find/extern.h
   head/usr.bin/find/find.1
   head/usr.bin/find/find.c
   head/usr.bin/find/function.c
   head/usr.bin/find/main.c
   head/usr.bin/find/option.c
 
 Modified: head/usr.bin/find/extern.h
 ==============================================================================
 --- head/usr.bin/find/extern.h	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/extern.h	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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;
 
 Modified: head/usr.bin/find/find.1
 ==============================================================================
 --- head/usr.bin/find/find.1	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/find.1	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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 na
  .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
 
 Modified: head/usr.bin/find/find.c
 ==============================================================================
 --- head/usr.bin/find/find.c	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/find.c	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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);
  }
 
 Modified: head/usr.bin/find/function.c
 ==============================================================================
 --- head/usr.bin/find/function.c	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/function.c	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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.
 
 Modified: head/usr.bin/find/main.c
 ==============================================================================
 --- head/usr.bin/find/main.c	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/main.c	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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 */
 
 Modified: head/usr.bin/find/option.c
 ==============================================================================
 --- head/usr.bin/find/option.c	Wed Jul 25 21:32:55 2012	(r238779)
 +++ head/usr.bin/find/option.c	Wed Jul 25 21:59:10 2012	(r238780)
 @@ -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 },
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jilles 
State-Changed-When: Sat Jul 28 14:34:24 UTC 2012 
State-Changed-Why:  
Fixed in 10-current. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169723 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/169723: commit references a PR
Date: Sun, 20 Apr 2014 16:41:36 +0000 (UTC)

 Author: jilles
 Date: Sun Apr 20 16:41:30 2014
 New Revision: 264699
 URL: http://svnweb.freebsd.org/changeset/base/264699
 
 Log:
   MFC r238780,r238948: 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 (original version)
   Relnotes:	yes
 
 Modified:
   stable/9/usr.bin/find/extern.h
   stable/9/usr.bin/find/find.1
   stable/9/usr.bin/find/find.c
   stable/9/usr.bin/find/function.c
   stable/9/usr.bin/find/main.c
   stable/9/usr.bin/find/option.c
 Directory Properties:
   stable/9/usr.bin/find/   (props changed)
 
 Modified: stable/9/usr.bin/find/extern.h
 ==============================================================================
 --- stable/9/usr.bin/find/extern.h	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/extern.h	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -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;
 
 Modified: stable/9/usr.bin/find/find.1
 ==============================================================================
 --- stable/9/usr.bin/find/find.1	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/find.1	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -468,7 +468,9 @@ is numeric and there is no such group na
  .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
 
 Modified: stable/9/usr.bin/find/find.c
 ==============================================================================
 --- stable/9/usr.bin/find/find.c	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/find.c	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -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);
  }
 
 Modified: stable/9/usr.bin/find/function.c
 ==============================================================================
 --- stable/9/usr.bin/find/function.c	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/function.c	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -977,6 +977,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.
 
 Modified: stable/9/usr.bin/find/main.c
 ==============================================================================
 --- stable/9/usr.bin/find/main.c	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/main.c	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -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;	/* ignore readdir race */
  int isdeprecated;		/* using deprecated syntax */
  int isdepth;			/* do directories on post-order visit */
  int isoutput;			/* user specified output operator */
 
 Modified: stable/9/usr.bin/find/option.c
 ==============================================================================
 --- stable/9/usr.bin/find/option.c	Sun Apr 20 16:34:10 2014	(r264698)
 +++ stable/9/usr.bin/find/option.c	Sun Apr 20 16:41:30 2014	(r264699)
 @@ -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 },
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jilles 
State-Changed-When: Sun Apr 20 16:57:37 UTC 2014 
State-Changed-Why:  
Also fixed in 9-stable. No MFC to older branches is planned. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169723 
>Unformatted:
