]> git.ipfire.org Git - thirdparty/coreutils.git/commit
cp: diagnose invalid "cp -rl dir dir" right away, once again
authorJim Meyering <meyering@redhat.com>
Fri, 27 Feb 2009 08:23:44 +0000 (09:23 +0100)
committerJim Meyering <meyering@redhat.com>
Fri, 27 Feb 2009 10:44:26 +0000 (11:44 +0100)
commitb50a4ae557d6ac479e659f685c8a8ff909e09393
tree3e6b78b6e906050985cfc6606fd877b8da2b640a
parent3a914fa76dab3a4ee3dd2683866eeb664f505a00
cp: diagnose invalid "cp -rl dir dir" right away, once again

Running "mkdir dir; cp -rl dir dir" would create dir/dir/dir/...
rather than diagnosing the "copy-into-self" failure.

The easy fix would have been to revert this part of the change
[3ece0355 2008-11-09 cp: use far less memory in some cases]
that introduced the bug:

-         remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev);
+         if (!x->hard_link)
+           remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev);

However, that would have induced the failure of the new cp/link-heap
test, due to the added memory pressure of recording 10k dev/ino pairs.
And besides, I liked that improvement and wanted to keep it.

Now that it's obvious recording the just-created-directory dev/ino
needn't depend on the setting of hard_link, I realized it is necessary
to record the pair only for the first directory created for each
source command-line argument.

I made that change, then noticed the new test, cp -rl a d d, would pass
when run once, yet output the into-self diagnostic twice.  Also note
the side effect: it creates d/a and d/d.  However, running that same
command a second time, now with the modified directory, would fail.

That turned out to be due to the fact that although the first into-self
failure was detected in copy_dir, that function would continue copying
other entries regardless -- and that would make it fail (eventually)
with the unwanted recursion.

* src/copy.c (copy_internal): This function needed an indicator of
whether, for a give command line argument, it had already created its
first directory.  If so, no more need to record dev/ino pairs.  If this
is the first, then do record its pair.  Hence, the new parameter.
(copy_dir, copy): Update callers.
(copy_dir): Upon any into-self failure, break out of the loop.
* tests/cp/into-self: Test for the above.
Reported by Mikael Magnusson.
NEWS
THANKS
src/copy.c
tests/cp/into-self