GNU bug report logs - #31335
unexpected cp -f behavior

Previous Next

Package: coreutils;

Reported by: Ernesto Alfonso <erjoalgo <at> gmail.com>

Date: Tue, 1 May 2018 18:15:02 UTC

Severity: normal

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 31335 in the body.
You can then email your comments to 31335 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Tue, 01 May 2018 18:15:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ernesto Alfonso <erjoalgo <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Tue, 01 May 2018 18:15:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ernesto Alfonso <erjoalgo <at> gmail.com>
To: bug-coreutils <at> gnu.org
Subject: unexpected cp -f behavior
Date: Tue, 01 May 2018 11:14:44 -0700
cp -f fails when destination is a recursive symlink:

    $ ln -s self self
    $ cat self 
    self: Too many levels of symbolic links
    $ touch a
    $ cp a self 
    cp: failed to access 'self': Too many levels of symbolic links
    $ cp -f a self 
    cp: failed to access 'self': Too many levels of symbolic links
    

From the man page:

       -f, --force
              if  an  existing destination file cannot be opened, remove it and try again (this option is ignored when
              the -n option is also used)

What am I missing?

Thanks,

Ernesto




Information forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Fri, 04 May 2018 04:31:01 GMT) Full text and rfc822 format available.

Message #8 received at 31335 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Ernesto Alfonso <erjoalgo <at> gmail.com>, 31335 <at> debbugs.gnu.org
Subject: Re: bug#31335: unexpected cp -f behavior
Date: Thu, 3 May 2018 21:30:39 -0700
[Message part 1 (text/plain, inline)]
On 01/05/18 11:14, Ernesto Alfonso wrote:
> 
> cp -f fails when destination is a recursive symlink:
> 
>     $ ln -s self self
>     $ cat self 
>     self: Too many levels of symbolic links
>     $ touch a
>     $ cp a self 
>     cp: failed to access 'self': Too many levels of symbolic links
>     $ cp -f a self 
>     cp: failed to access 'self': Too many levels of symbolic links
>     
> 
>>From the man page:
> 
>        -f, --force
>               if  an  existing destination file cannot be opened, remove it and try again (this option is ignored when
>               the -n option is also used)

Note cp will still write through symlinks with -f.
For example with dangling symlinks one gets:
  cp: not writing through dangling symlink '...'
I.E. -f currently only removes the symlink if
the destination exists but can't be opened.
This looks to be an explicit decision which I'd be reluctant to change.
I've added a test and some docs to make this apparent.

Now there is also the --remove-destination option
which is a more explicit request to always delete
the destination first. Would that suffice?
Note that doesn't even work currently,
so the attached enables that, so that command line args
are treated similarly to traversed files.

cheers,
Pádraig
[cp--remove-symlink.patch (text/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Fri, 04 May 2018 06:25:02 GMT) Full text and rfc822 format available.

Message #11 received at 31335 <at> debbugs.gnu.org (full text, mbox):

From: Ernesto Alfonso <erjoalgo <at> gmail.com>
To: 31335 <at> debbugs.gnu.org
Subject: Fwd: bug#31335: unexpected cp -f behavior
Date: Thu, 3 May 2018 23:24:47 -0700
[Message part 1 (text/plain, inline)]
did not reply all

---------- Forwarded message ----------
From: Ernesto Alfonso <erjoalgo <at> gmail.com>
Date: Thu, May 3, 2018 at 11:10 PM
Subject: Re: bug#31335: unexpected cp -f behavior
To: Pádraig Brady <P <at> draigbrady.com>


To be honest, I think cp -f should behave consistently with rm -f.

    $ ln -s self self
    $ rm -f self
    $ echo $?
    0

It's also what I would expect, if I use -f, I expect cp will do everything
it can to force the operation and succeed if all possible.

Reading the man page, --remove-destination and --force seem to just swap
the cp, rm operation, i.e.

--force:                     "cp; if fail, rm; cp"
--remove-destination: "rm; cp"

In either case it seems that the "rm" part should correctly handle a
recursive symlink.

This is my opinion as a user of cp and I'm not familiar with the
implementation or design decisions.

Thanks,

Ernesto



On Thu, May 3, 2018 at 9:30 PM, Pádraig Brady <P <at> draigbrady.com> wrote:

> On 01/05/18 11:14, Ernesto Alfonso wrote:
> >
> > cp -f fails when destination is a recursive symlink:
> >
> >     $ ln -s self self
> >     $ cat self
> >     self: Too many levels of symbolic links
> >     $ touch a
> >     $ cp a self
> >     cp: failed to access 'self': Too many levels of symbolic links
> >     $ cp -f a self
> >     cp: failed to access 'self': Too many levels of symbolic links
> >
> >
> >>From the man page:
> >
> >        -f, --force
> >               if  an  existing destination file cannot be opened, remove
> it and try again (this option is ignored when
> >               the -n option is also used)
>
> Note cp will still write through symlinks with -f.
> For example with dangling symlinks one gets:
>   cp: not writing through dangling symlink '...'
> I.E. -f currently only removes the symlink if
> the destination exists but can't be opened.
> This looks to be an explicit decision which I'd be reluctant to change.
> I've added a test and some docs to make this apparent.
>
> Now there is also the --remove-destination option
> which is a more explicit request to always delete
> the destination first. Would that suffice?
> Note that doesn't even work currently,
> so the attached enables that, so that command line args
> are treated similarly to traversed files.
>
> cheers,
> Pádraig
>
[Message part 2 (text/html, inline)]

Reply sent to Pádraig Brady <P <at> draigBrady.com>:
You have taken responsibility. (Tue, 15 May 2018 17:07:02 GMT) Full text and rfc822 format available.

Notification sent to Ernesto Alfonso <erjoalgo <at> gmail.com>:
bug acknowledged by developer. (Tue, 15 May 2018 17:07:02 GMT) Full text and rfc822 format available.

Message #16 received at 31335-done <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Ernesto Alfonso <erjoalgo <at> gmail.com>, 31335-done <at> debbugs.gnu.org
Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior
Date: Tue, 15 May 2018 10:05:56 -0700
On 03/05/18 23:24, Ernesto Alfonso wrote:
> did not reply all
> 
> ---------- Forwarded message ----------
> From: Ernesto Alfonso <erjoalgo <at> gmail.com>
> Date: Thu, May 3, 2018 at 11:10 PM
> Subject: Re: bug#31335: unexpected cp -f behavior
> To: Pádraig Brady <P <at> draigbrady.com>
> 
> 
> To be honest, I think cp -f should behave consistently with rm -f.
> 
>     $ ln -s self self
>     $ rm -f self
>     $ echo $?
>     0
> 
> It's also what I would expect, if I use -f, I expect cp will do everything
> it can to force the operation and succeed if all possible.

Maybe, though that's worth further consideration.
For example rm -f doesn't do everything possible to allow deleting a file.
What if the symlinks where only temporarily dangling due to unmounted dest
for example.

I've pushed at the fix for --remove at:
https://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.29-36-ga391007

marking this as done

cheers,
Pádraig.




Information forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Wed, 16 May 2018 00:12:01 GMT) Full text and rfc822 format available.

Message #19 received at 31335 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: 31335 <at> debbugs.gnu.org, P <at> draigBrady.com, erjoalgo <at> gmail.com
Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior
Date: Tue, 15 May 2018 17:11:25 -0700
On 05/15/2018 10:05 AM, Pádraig Brady wrote:
>> It's also what I would expect, if I use -f, I expect cp will do everything
>> it can to force the operation and succeed if all possible.
> Maybe, though that's worth further consideration.

POSIX is arguably ambiguous about what 'cp -f S D' should do if D is a 
symlink to itself. POSIX says that if D "exists", then cp must try to 
unlink and then re-create D; and that if D does not "exist", cp must 
fail. So, if one considers a self-symlink as "existing", then GNU cp 
doesn't conform to POSIX; if one considers such a symlink as not 
"existing", then GNU cp conforms. Unfortunately, as far as I can tell 
POSIX never exactly defines what "exists" means in this context.

That being said, POSIX uses nearly the same wording for 'ln -f' that it 
does for 'cp -f', which implies that cp should be consistent with ln, 
and GNU ln (like most ln implementations) treat self-symlinks as 
"existing" in this case. Also, other implementations of cp seem act like 
ln does here, so they interpret the ambiguity in POSIX the opposite way 
that GNU cp does. Furthermore, I think that users by and large expect 
the non-GNU interpretation where 'cp -f' is like 'ln -f'. For all these 
reasons, I'm inclined to think that GNU cp should fall into line here.





Information forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Wed, 16 May 2018 07:04:02 GMT) Full text and rfc822 format available.

Message #22 received at 31335 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>, 31335 <at> debbugs.gnu.org, erjoalgo <at> gmail.com
Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior
Date: Wed, 16 May 2018 00:03:00 -0700
[Message part 1 (text/plain, inline)]
On 15/05/18 17:11, Paul Eggert wrote:
> On 05/15/2018 10:05 AM, Pádraig Brady wrote:
>>> It's also what I would expect, if I use -f, I expect cp will do everything
>>> it can to force the operation and succeed if all possible.
>> Maybe, though that's worth further consideration.
> 
> POSIX is arguably ambiguous about what 'cp -f S D' should do if D is a 
> symlink to itself. POSIX says that if D "exists", then cp must try to 
> unlink and then re-create D; and that if D does not "exist", cp must 
> fail. So, if one considers a self-symlink as "existing", then GNU cp 
> doesn't conform to POSIX; if one considers such a symlink as not 
> "existing", then GNU cp conforms. Unfortunately, as far as I can tell 
> POSIX never exactly defines what "exists" means in this context.

Well `test -e self-symlink` => does not exist

> That being said, POSIX uses nearly the same wording for 'ln -f' that it 
> does for 'cp -f', which implies that cp should be consistent with ln, 
> and GNU ln (like most ln implementations) treat self-symlinks as 
> "existing" in this case. Also, other implementations of cp seem act like 
> ln does here, so they interpret the ambiguity in POSIX the opposite way 
> that GNU cp does. Furthermore, I think that users by and large expect 
> the non-GNU interpretation where 'cp -f' is like 'ln -f'. For all these 
> reasons, I'm inclined to think that GNU cp should fall into line here.

Agreed. I can't think of a case where replacing a self symlink
is not what you'd want to happen.

Proposed patch is attached.

cheers,
Pádraig
[cp-f-eloop.patch (text/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#31335; Package coreutils. (Fri, 18 May 2018 03:55:02 GMT) Full text and rfc822 format available.

Message #25 received at 31335 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: 31335 <at> debbugs.gnu.org, erjoalgo <at> gmail.com
Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior
Date: Thu, 17 May 2018 20:54:03 -0700
On 16/05/18 00:03, Pádraig Brady wrote:
> Agreed. I can't think of a case where replacing a self symlink
> is not what you'd want to happen.
> 
> Proposed patch is attached.

Now pushed at:
https://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.29-37-gc732388

cheers,
Pádraig





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 15 Jun 2018 11:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 315 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.