Subject: bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.

From: Jim Meyering <[email-masked]>
Date: Tue, 04 Sep 2012 17:02:42 +0200

Bernhard Voelker wrote:
> On 09/04/2012 02:55 PM, Jim Meyering wrote:
>> With the following patch, I see new behavior.
>> It's an improvement, but we're still not there:
>>
>>     $ mkdir -p d/e/f; ln -s d s; rm -r s/
>>     rm: cannot remove 's/': Not a directory
>>     [Exit 1]
>>     $ find
>>     .
>>     ./s
>>     ./d
>>
>> Notice how it did traverse s/ into d/, and removed d/e and d/e/f.
>> The only problem is that when it attempted to remove the command-line
>> specified "s/", unlinkat (AT_FDCWD, "s/", AT_REMOVEDIR) failed:
>>
>>     unlinkat(4, "d", 0)                     = 0
>>     unlinkat(5, "f", AT_REMOVEDIR)          = 0
>>     unlinkat(4, "e", AT_REMOVEDIR)          = 0
>>     unlinkat(AT_FDCWD, "s/", AT_REMOVEDIR)  = -1 ENOTDIR (Not a directory)
>>     rm: cannot remove 's/': Not a directory
>>     +++ exited with 1 +++
>>
>> Now, this looks like a problem with unlinkat.
>
> Hmm, what about dereferencing command line symlinks with trailing
> slashes _before_ entering the FTS loop instead?

Thanks, but I'm pretty sure that would be too much work to perform
on any slash-decorated operand.

Besides, I'm not 100% sold on the idea that that final unlinkat
call should be creating a dangling symlink (i.e., by removing
the directory to which "s" points).