The following reply was made to PR bin/169723; it has been noted by GNATS.

From: Andrey Ignatov <[email protected]>
To: Jilles Tjoelker <[email protected]>
Cc: [email protected], Valery Khromov <[email protected]>
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 <[email protected]> [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--
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to