Subject: bug#8381: cp inconsistency

From: Eric Blake <[email-masked]>
Date: Wed, 30 Mar 2011 08:03:45 -0600

On 03/30/2011 05:56 AM, Thomas Hofmann wrote:
> Hello,
> 
> two issues:
> 1) manpage of cp contains obsolete email-address for bug-reporting

The man page is generated from 'cp --help' output; on my Fedora 14
machine, I see this for 'man cp'

REPORTING BUGS
       Report cp bugs to [email-masked]
...
GNU coreutils 8.5                November 2010
 CP(1)

If the man page doesn't end with the same version as 'cp --version',
then your man pages are out of date, and that is an installation problem
on your end (or perhaps something you should take up with your distro);
if it _is_ up-to-date, then the reporting bugs address should match.  If
it doesn't, then paste what you actually see before claiming that it is
wrong.

> 2) cp inconsistency when copying a directory to a) a non existing
> directory, or b) to an existing directory. Further elaborated below.
> 
> cp -a SOME_DIR NOT_YET_EXISTING_DIR
> 
> results in a new directory directly containing each entry of SOME_DIR
> 
> while:
> CP -a SOME_DIR EXISTING_DIR

Did you mean 'cp' instead of 'CP'?

> 
> results in EXISTING_DIR/SOME_DIR

This is not a bug - the dual behavior is mandated by POSIX, which
specifically requires that cp first stat() the last argument, then act
differently depending on whether that argument was an existing directory
or not.

> 
> The first result seems to be a reasonable outcome in both cases.
> Appending "/" to the directory-names should lead to the same result.

To the source or to the destination, or to both?

> While appending "/." to the target-directory would change the meaning,
> and rather lead to the result of the observed second version.

I'm not sure I follow what you think is wrong or unintuitive.  So the
best I can do is state what POSIX requires, and that I believe that GNU
cp meets those requirements:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html

The first synopsis form is denoted by two operands, neither of which are
existing files of type directory. The cp utility shall copy the contents
of source_file (or, if source_file is a file of type symbolic link, the
contents of the file referenced by source_file) to the destination path
named by target_file.

The second synopsis form is denoted by two or more operands where the -R
option is not specified and the first synopsis form is not applicable.
It shall be an error if any source_file is a file of type directory, if
target does not exist, or if target does not name a directory. The cp
utility shall copy the contents of each source_file (or, if source_file
is a file of type symbolic link, the contents of the file referenced by
source_file) to the destination path named by the concatenation of
target, a single <slash> character if target did not end in a <slash>,
and the last component of source_file.

The third synopsis form is denoted by two or more operands where the -R
option is specified. The cp utility shall copy each file in the file
hierarchy rooted in each source_file to a destination path named as follows:

    * If target exists and names an existing directory, the name of the
corresponding destination path for each file in the file hierarchy shall
be the concatenation of target, a single <slash> character if target did
not end in a <slash>, and the pathname of the file relative to the
directory containing source_file.
    * If target does not exist and two operands are specified, the name
of the corresponding destination path for source_file shall be target;
the name of the corresponding destination path for all other files in
the file hierarchy shall be the concatenation of target, a <slash>
character, and the pathname of the file relative to source_file.

-- 
Eric Blake   [email-masked]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org