Subject: Re: coreutils-8.14, "rm -r" fails with EBADF

From: Jim Meyering <[email-masked]>
Date: Thu, 15 Dec 2011 15:17:07 +0100

Joachim Schmitz wrote:
> I got coreutils-8.9, 8.13 and 8.14 to compile for my platform, and most of the

Thanks for the report.
More details will help us help you:

Which platform is that?
Including your config.h might help.

> utilities work, but as soon as it comes to recurring thru the file system some
> utils fail, e.g.:
>
> ~/coreutils-8.14/src $ ./rm -R /tmp/foo
>
> ./rm: traversal failed: `/tmp/foo': Bad file descriptor
>
> ~/coreutils-8.14/src $ ./rm -r /tmp/foo
>
> ./rm: traversal failed: `/tmp/foo': Bad file descriptor
>
> ~/coreutils-8.14/src $
>
> ‘./ls –R /tmp/foo’ does work though:
>
> ~/coreutils-8.14/src $ ./ls -lr /tmp/foo
>
> total 0
>
> -rw-rw-r-- 1 jojo ITUGLIB 0 Dec 15 08:06 bar
>
> Does this ring a bell with one of you?

I haven't seen that before.
It's obviously coming from this:

    case FTS_ERR:
      /* Various failures, from opendir to ENOMEM, to failure to "return"
         to preceding directory, can provoke this.  */
      error (0, ent->fts_errno, _("traversal failed: %s"),
             quote (ent->fts_path));
      fts_skip_tree (fts, ent);
      return RM_ERROR;

but what I really need to know is what happened just prior, in fts_read.
Can you run gdb, set a breakpoint in fts_read and show us the result of
stepping through fts_read?  That would be most useful.

Or can you run strace -o log ./rm -r /tmp/foo
and send us the "log" file?

> I don’t understand why one fails but the other works, and can’t seem to fine the
> place where it goes wrong.

rm (and du, chmod, chown, etc.) use fts for tree traversal, while ls
still uses hand-rolled (and thus unnecessarily limited) recursion.