bug-findutils
[Top][All Lists]
Advanced

[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
website.

> 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)
though:-

  $ for f in ./find-* ; do echo $f; find ~/tmp -empty -printf "$f fails\n"; done
  ./find-4.1.20
  ./find-4.2.0
  ./find-4.2.1
  ./find-4.2.10
  ./find-4.2.11
  ./find-4.2.12
  ./find-4.2.13
  ./find-4.2.14
  ./find-4.2.15
  ./find-4.2.16
  ./find-4.2.17
  ./find-4.2.18
  ./find-4.2.19
  ./find-4.2.2
  ./find-4.2.20
  ./find-4.2.21
  ./find-4.2.22
  ./find-4.2.23
  ./find-4.2.24
  ./find-4.2.25
  ./find-4.2.3
  ./find-4.2.4
  ./find-4.2.5
  ./find-4.2.6
  ./find-4.2.7
  ./find-4.2.8
  ./find-4.2.9

  address@hidden:~/source/GNU/findutils/installed/bin$ ls -lRa ~/tmp
  /home/james/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
   expected.

The implementation of "-empty" is this:-

boolean
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;
              break;
            }
        }
      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);
  else
    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
code. 


> Should this go to another list?

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

Regards,
James.





reply via email to

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