Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Dec 2012 23:16:45 GMT
From:      "Micha&#322; G&#243;rny" <mgorny@gentoo.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/174489: 'cp -a -n' fails when 'over-writing' a broken symlink
Message-ID:  <201212162316.qBGNGjRB001129@red.freebsd.org>
Resent-Message-ID: <201212162320.qBGNK10X076432@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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&#322; G&#243;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@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212162316.qBGNGjRB001129>