[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

find .. -empty spuriously returning true (was: Re: place for find bugs?)

From: James Youngman
Subject: find .. -empty spuriously returning true (was: Re: place for find bugs?)
Date: Sun, 4 Sep 2005 21:43:29 +0100
User-agent: Mutt/1.5.9i

On Sun, Sep 04, 2005 at 10:24:08AM -0700, Linda A. Walsh wrote:


Hello again, I take it you've changed job since we last corresponded
in May 2005.

> Is find considered a "core util"? or where should I report a 'find' bug?

See the output of "find --help".

Discussion of find (and locate and xargs) takes place at
address@hidden  Bugs should be reported via the bug tracker at
<http://savannah.gnu.org/bugs/?group=findutils>.  Those without web
access are very welcome to report bugs by email rather than use the

> I ran into something I'd consider a bug in find:
> was trying to clear out empty directories using the "-empty" predicate.
> It returns "true" in the case of a directory full of "symlinks" (at
> least on an xfs file system under SuSE 9.3, package findutils-4.2.19-3.1.).

Firstly, there are no upstream releases of the form findutils 4.2.19.*
other than 4.2.19 itself.  The trailing version numbering presumably
relates to some patches or packaging done by SuSE.  I have no idea
what bugs might have been fixed - or introduced - by those patches.

As for the behaviour you describe, that should not happen.  For any
given directory, the -empty predicate should return false under all
circumstances UNLESS readir() on that directory returns no entries
other than "." and "..".  Even then, if readdir() also reports an
error, -empty will still return false.

> While there may be no file space allocated for files or directories under
> the directory, it seems there may very well be space taken up by symlinks
> themselves and even though they may be held within the minimum allocation
> unit of the directory block (4k, I believe), I don't regard that as "empty".
> It still is taking up 1 block by it's existance.  ;-/

For directories, find understand "empty" to mean 

  1. a directory which contains no directory entries.  
  2. a regular file which has a size of zero.

Other file types (devices, sockets, doors, symbolic links) are
themselves deemed non-empty.  A directory containing only empty things
is still deemed not to be empty.

I'm having trouble reproducing the problem with vanilla upstream
versions of findutils between 4.1.20 and 4.2.25 (released today)

  $ for f in ./find-* ; do echo $f; find ~/tmp -empty -printf "$f fails\n"; done

  address@hidden:~/source/GNU/findutils/installed/bin$ ls -lRa ~/tmp
  total 20
  drwxr-xr-x    2 james users  4096 2005-09-04 21:11 .
  drwx--x--x  196 james users 16384 2005-09-04 09:45 ..
  lrwxrwxrwx    1 james users     4 2005-09-04 21:11 bar -> /usr
  lrwxrwxrwx    1 james users     4 2005-09-04 21:11 foo -> /tmp

  address@hidden:~/source/GNU/findutils/installed/bin$ rm  ~/tmp/*

  address@hidden:~/source/GNU/findutils/installed/bin$ for f in ./find-* ; do 
find ~/tmp -empty -o -printf "$f fails\n"; done

  (the last command produced no output)

Possibilities I would consider are:-

1. Something to do with your execution environment (XFS, your kernel
   version, C library, and so on) is exposing a bug in find which I
   can't see because my environment is different.

2. The way in which your version of findutils is patched or built 
   exposes a defect in GNU find.

3. The patched version of find you're using somehow introduces a problem.

4. Perhaps your "find" command line didn't actually mean what you

The implementation of "-empty" is this:-

pred_empty (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
  (void) pathname;
  (void) pred_ptr;
  if (S_ISDIR (stat_buf->st_mode))
      DIR *d;
      struct dirent *dp;
      boolean empty = true;

      errno = 0;
      d = opendir (state.rel_pathname);
      if (d == NULL)
          error (0, errno, "%s", pathname);
          state.exit_status = 1;
          return false;
      for (dp = readdir (d); dp; dp = readdir (d))
          if (dp->d_name[0] != '.'
              || (dp->d_name[1] != '\0'
                  && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
              empty = false;
      if (CLOSEDIR (d))
          error (0, errno, "%s", pathname);
          state.exit_status = 1;
          return false;
      return (empty);
  else if (S_ISREG (stat_buf->st_mode))
    return (stat_buf->st_size == 0);
    return (false);

I can't immediately see a problem with it, so perhaps you could
investigate some of the above possibilities.  A useful way to start
might be to download a vanilla version of findutils-4.2.25 from
ftp.gnu.org.  At least that way we'll be staring at the same set of

> Should this go to another list?

Yes, as mentioned above.  I have posted this reply to that list, and
not to <address@hidden>.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]