Subject: bug#16889: erratic behavior of cp command i.e while copying files (using *) from one directory to another directory

From: Anil Kumar <[email-masked]>
Date: Wed, 26 Feb 2014 18:06:54 +0530

Hello

I have observed, one erratic behavior of cp command i.e while copying
files (using *) from one directory to another directory if
we miss destination directory then cp command copies content of 1st
file into 2nd file of same source directory instead of giving any
error.

Here is the scenario:

#ls -l
total 8
drwxr-xr-x 2 root root 4096 Feb 26 17:34 ddir
drwxr-xr-x 2 root root 4096 Feb 26 17:36 sdir

# echo "hello" > sdir/hello.txt
# echo "bye" > sdir/bye.txt

# cat sdir/hello.txt
hello

# cat sdir/bye.txt
bye

# cp sdir/*.txt

# cat sdir/hello.txt
bye

# cat sdir/bye.txt
bye

[Anil] Not sure, why "cp sdir/*.txt" command has copied data of
bye.txt into hello.txt ? I think, its not desired behavior.
 'cp' command should have produced error e.g destination is missing etc .

One more example of similar behavior:
# echo "hello" > sdir/hello.txt
# echo "bye" > sdir/bye.txt

# cat sdir/hello.txt
hello

# cat sdir/bye.txt
bye

# cp sdir/*

# cat sdir/hello.txt
bye

# cat sdir/bye.txt
bye

[Anil]Here again "bye" has been copied into hello.txt which is not
desired behavior.

Here is strace output command "strace  cp sdir/*"

stat("sdir/hello.txt", {st_mode=S_IFREG|0644, st_size=6, ...}) = 0
stat("sdir/bye.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("sdir/hello.txt", {st_mode=S_IFREG|0644, st_size=6, ...}) = 0
open("sdir/bye.txt", O_RDONLY)          = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
open("sdir/hello.txt", O_WRONLY|O_TRUNC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "bye\n", 65536)                 = 4
write(4, "bye\n", 4)                    = 4
read(3, "", 65536)                      = 0
close(4)                                = 0
close(3)                                = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?