diff options
author | Jim Meyering <meyering@redhat.com> | 2009-02-27 09:23:44 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-02-27 11:44:26 +0100 |
commit | b50a4ae557d6ac479e659f685c8a8ff909e09393 (patch) | |
tree | 3e6b78b6e906050985cfc6606fd877b8da2b640a /tests/cp | |
parent | 3a914fa76dab3a4ee3dd2683866eeb664f505a00 (diff) | |
download | coreutils-b50a4ae557d6ac479e659f685c8a8ff909e09393.tar.xz |
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.
Diffstat (limited to 'tests/cp')
-rwxr-xr-x | tests/cp/into-self | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/tests/cp/into-self b/tests/cp/into-self index ee3fcf5fd..cd8723236 100755 --- a/tests/cp/into-self +++ b/tests/cp/into-self @@ -1,7 +1,7 @@ #!/bin/sh # Confirm that copying a directory into itself gets a proper diagnostic. -# Copyright (C) 2001, 2002, 2004, 2006-2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2004, 2006-2009 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,15 +28,32 @@ fi . $srcdir/test-lib.sh -mkdir dir || framework_failure +mkdir a dir || framework_failure fail=0 # This command should exit nonzero. cp -R dir dir 2> out && fail=1 +echo 1 >> out + +# This should, too. However, with coreutils-7.1 it would infloop. +cp -rl dir dir 2>> out && fail=1 +echo 2 >> out + +cp -rl a dir dir 2>> out && fail=1 +echo 3 >> out +cp -rl a dir dir 2>> out && fail=1 +echo 4 >> out cat > exp <<\EOF cp: cannot copy a directory, `dir', into itself, `dir/dir' +1 +cp: cannot copy a directory, `dir', into itself, `dir/dir' +2 +cp: cannot copy a directory, `dir', into itself, `dir/dir' +3 +cp: cannot copy a directory, `dir', into itself, `dir/dir' +4 EOF #' |