misc/174489: 'cp -a -n' fails when 'over-writing' a broken symlink
Michał Górny
mgorny at gentoo.org
Sun Dec 16 23:20:02 UTC 2012
>Number: 174489
>Category: misc
>Synopsis: 'cp -a -n' fails when 'over-writing' a broken symlink
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Dec 16 23:20:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Michał Górny
>Release: 8.2-RELEASE-p2
>Organization:
>Environment:
FreeBSD sand 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #0: Sun Aug 21 21:47:45 UTC 2011 root at onepiece:/secure/usr/obj/secure/usr/src/sys/ONE-PIECE amd64
>Description:
If 'cp -a -n' is used to copy a tree of files containing a 'broken' symlink for the second time, the call fails with the following error:
cp: symlink: python-exec: File exists
(with 'python-exec' being the non-existent target of the broken symlink, not the symlink name)
I would assume that the no-clobber behavior enforced by '-n' should actually ignore the symlink, broken or not.
The bug was originally reported on Gentoo Bugzilla because of an eclass not working with BSD version of 'cp' [0]. A detailed analysis of the problem has been submitted there by Mike Gilbert, citing:
> Inside of copy() in cp.c [1], the dne variable is set to 1 based on a call
> to stat(2). stat(2) attempts to follow symlinks, and returns -1 when called
> on the easy_install -> python-exec symlink because python-exec doesn't exist
> in ${D}.
>
> !dne is then passed to copy_link in utils.c [2]. copy_link is supposed to
> remove the destination if it exists (via unlink), but the bad value in dne
> causes this to be skipped.
>
> Since the destination file is not removed, the call to symlink then fails,
> producing the "cp: symlink: python-exec: File exists" message.
>
> [1] http://svnweb.freebsd.org/base/head/bin/cp/cp.c?view=markup
> [2] http://svnweb.freebsd.org/base/head/bin/cp/utils.c?view=markup
[0]:https://bugs.gentoo.org/show_bug.cgi?id=447370
>How-To-Repeat:
mkdir 1 2
ln -s python-exec 1/foo
cp -a -n 1/* 2/
cp -a -n 1/* 2/
>Fix:
Citing Mike Gilbert:
> I think this could be fixed by changing the stat(2) to lstat(2) in cp.c.
> copy_link should probably be changed to obey the "-n" flag (nflag) as well.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list