From unknown Sat Aug 09 13:01:20 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#31335 <31335@debbugs.gnu.org> To: bug#31335 <31335@debbugs.gnu.org> Subject: Status: unexpected cp -f behavior Reply-To: bug#31335 <31335@debbugs.gnu.org> Date: Sat, 09 Aug 2025 20:01:20 +0000 retitle 31335 unexpected cp -f behavior reassign 31335 coreutils submitter 31335 Ernesto Alfonso severity 31335 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Tue May 01 14:15:01 2018 Received: (at submit) by debbugs.gnu.org; 1 May 2018 18:15:01 +0000 Received: from localhost ([127.0.0.1]:46030 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fDZnn-0001AG-Hx for submit@debbugs.gnu.org; Tue, 01 May 2018 14:14:59 -0400 Received: from eggs.gnu.org ([208.118.235.92]:41443) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fDZnl-0001A4-VE for submit@debbugs.gnu.org; Tue, 01 May 2018 14:14:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDZnf-0006yq-Pz for submit@debbugs.gnu.org; Tue, 01 May 2018 14:14:52 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=BAYES_40,FREEMAIL_FROM, T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:34079) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fDZnf-0006yk-Ln for submit@debbugs.gnu.org; Tue, 01 May 2018 14:14:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60638) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fDZne-0003bk-Ox for bug-coreutils@gnu.org; Tue, 01 May 2018 14:14:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fDZnd-0006y6-VK for bug-coreutils@gnu.org; Tue, 01 May 2018 14:14:50 -0400 Received: from mail-oi0-x229.google.com ([2607:f8b0:4003:c06::229]:43011) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fDZnd-0006xl-OR for bug-coreutils@gnu.org; Tue, 01 May 2018 14:14:49 -0400 Received: by mail-oi0-x229.google.com with SMTP id p62-v6so10725382oie.10 for ; Tue, 01 May 2018 11:14:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:user-agent:mime-version; bh=e+DbCZl15nrPZn9dnRnrW0i7Xy/mIBOLsQXWVbIr8H4=; b=IMDvUoSYWhJrsr3q6jKYkn53K6NaQLbyj0mRuiotXgNX9WjTfhNIDqUdkFPUr1cHp6 AKH49TGfBcXhEOWiZ1JG0XcrdBSDgP+Jebb/akVaLrueWxf1pGyIyUluPv/tafV1ovHP RZYugFHWlKUqeBxa8uBLD0cKU7nV1W3RbinSVqJ1VEfCU0nh84bgWj/6IydIln6Z7vTB BgfqJDGnLCFTbC6fg7yZtCQpvUU8y2ca4q7Ca/RLBPU47vzEHoXDGGgxAAMd7aQIIzLP eYKluGcdroQa3RPLzLfKOJ5nVJbgoGZtR1393BF6ldA/dTu8m7r5gZ+QjtIkoLugjhD7 HnFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=e+DbCZl15nrPZn9dnRnrW0i7Xy/mIBOLsQXWVbIr8H4=; b=BbOxcBZVW8xoZlW1jx6wF4qXQofoyptAmsZx4QGmiK1YIDGrqKgg62MJevXWgy0xsK xNsutX3Q6wYZHo0WFrn372o2CN8QjKzBglGY5b3YBYl/87UXtJ7piphzmdsJxElilVIg i4sU1p6BEohbn6DfApOPl8YGBwssJBk9+PPJ5C4CpAFRCmXt/k675N7RNm5Lt2viqfB+ Qn2TOyWr29IAGtIMd1nS+Grm323qkM8q7A5VXx9Fh4G0a0K2WJl6f+gl/9mQ6gcr1Vby sEKAUK7CLBC+Eg9VRqRFhWyULF6QP0aLAFo0HhV9q8AuqUG9XUCMLkOBNw58Zrqly4Zb CL7g== X-Gm-Message-State: ALQs6tCPO9iewQ1Hi9o061GBaVwK4dv+VK9hpkqm756qxe2nlff5u+Hw 7NfL/DtV1RFCEfefN4Fh1Yc783ps X-Google-Smtp-Source: AB8JxZpxb4tLSwT/ygeUBBnY6DTL0aJfxwYLgcd1mmsXfrIKzSzRfW2vDuaK8RoKR25cZzBmc6Twmg== X-Received: by 2002:aca:d60d:: with SMTP id n13-v6mr9447138oig.189.1525198488284; Tue, 01 May 2018 11:14:48 -0700 (PDT) Received: from debian-x1 ([2600:1700:b940:1620:2677:3ff:fe25:8aac]) by smtp.gmail.com with ESMTPSA id i31-v6sm8938969otb.62.2018.05.01.11.14.46 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 01 May 2018 11:14:47 -0700 (PDT) From: Ernesto Alfonso To: bug-coreutils@gnu.org Subject: unexpected cp -f behavior Date: Tue, 01 May 2018 11:14:44 -0700 Message-ID: <87tvrrckff.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -4.0 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) 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 From debbugs-submit-bounces@debbugs.gnu.org Fri May 04 00:30:45 2018 Received: (at 31335) by debbugs.gnu.org; 4 May 2018 04:30:45 +0000 Received: from localhost ([127.0.0.1]:48783 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fESMm-0000Fk-Mz for submit@debbugs.gnu.org; Fri, 04 May 2018 00:30:45 -0400 Received: from mail.magicbluesmoke.com ([82.195.144.49]:46882) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fESMk-0000Fa-RZ for 31335@debbugs.gnu.org; Fri, 04 May 2018 00:30:43 -0400 Received: from localhost.localdomain (unknown [76.21.115.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.magicbluesmoke.com (Postfix) with ESMTPSA id 3F930A2B2; Fri, 4 May 2018 05:30:41 +0100 (IST) Subject: Re: bug#31335: unexpected cp -f behavior To: Ernesto Alfonso , 31335@debbugs.gnu.org References: <87tvrrckff.fsf@gmail.com> From: =?UTF-8?Q?P=c3=a1draig_Brady?= Message-ID: <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> Date: Thu, 3 May 2018 21:30:39 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <87tvrrckff.fsf@gmail.com> Content-Type: multipart/mixed; boundary="------------E15603AAF0C52AFCCA3360BF" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 31335 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) This is a multi-part message in MIME format. --------------E15603AAF0C52AFCCA3360BF Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit 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 --------------E15603AAF0C52AFCCA3360BF Content-Type: text/x-patch; name="cp--remove-symlink.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="cp--remove-symlink.patch" >From fb35d840935e7927f6d9f018d36fe544f6e376df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 3 May 2018 21:19:15 -0700 Subject: [PATCH] cp: ensure --remove-destination doesn't traverse symlinks * src/cp.c (target_directory_operand): Allow through inaccessible arguments with -f or --remove. * doc/coreutils.texi (cp invocation): Clarify that -f doesn't directly impact the removal of non-traversable symlinks. * tests/cp/dir-rm-dest.sh: Test the new behavior. * tests/cp/thru-dangling.sh: Enforce -f behavior wrt symlinks. * NEWS: Mention the bug fix. Fixes https://bugs.gnu.org/31335 --- NEWS | 4 ++++ doc/coreutils.texi | 3 ++- src/cp.c | 26 +++++++++++++++++--------- tests/cp/dir-rm-dest.sh | 7 ++++++- tests/cp/thru-dangling.sh | 9 +++++---- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index de02814..3f34a11 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,10 @@ GNU coreutils NEWS -*- outline -*- Previously it would have set executable bits on created special files. [bug introduced with coreutils-8.20] + 'cp --remove-destination file symlink' now removes the symlink + even if it can't be traversed. + [bug introduced with --remove-destination in fileutils-4.1.1] + ls no longer truncates the abbreviated month names that have a display width between 6 and 12 inclusive. Previously this would have output ambiguous months for Arabic or Catalan locales. diff --git a/doc/coreutils.texi b/doc/coreutils.texi index cdde136..c8d9bd9 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -8534,7 +8534,8 @@ Equivalent to @option{--no-dereference --preserve=links}. When copying without this option and an existing destination file cannot be opened for writing, the copy fails. However, with @option{--force}, when a destination file cannot be opened, @command{cp} then -tries to recreate the file by first removing it. +tries to recreate the file by first removing it. Note @option{--force} +alone will not remove symlinks that can't be traversed. When this option is combined with @option{--link} (@option{-l}) or @option{--symbolic-link} (@option{-s}), the destination link is replaced, and unless diff --git a/src/cp.c b/src/cp.c index 04ceb868..04cbd4b 100644 --- a/src/cp.c +++ b/src/cp.c @@ -559,23 +559,27 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, /* FILE is the last operand of this command. Return true if FILE is a directory. - But report an error and exit if there is a problem accessing FILE, - or if FILE does not exist but would have to refer to an existing - directory if it referred to anything at all. - If the file exists, store the file's status into *ST. + Without -f, report an error and exit if FILE exists + but can't be accessed. + + If the file exists and is accessible store the file's status into *ST. Otherwise, set *NEW_DST. */ static bool -target_directory_operand (char const *file, struct stat *st, bool *new_dst) +target_directory_operand (char const *file, struct stat *st, + bool *new_dst, bool forcing) { int err = (stat (file, st) == 0 ? 0 : errno); bool is_a_dir = !err && S_ISDIR (st->st_mode); if (err) { - if (err != ENOENT) + if (err == ENOENT) + *new_dst = true; + else if (forcing) + st->st_mode = 0; /* clear so we don't enter --backup case below. */ + else die (EXIT_FAILURE, err, _("failed to access %s"), quoteaf (file)); - *new_dst = true; } return is_a_dir; } @@ -590,6 +594,8 @@ do_copy (int n_files, char **file, const char *target_directory, struct stat sb; bool new_dst = false; bool ok = true; + bool forcing = x->unlink_dest_before_opening + || x->unlink_dest_after_failed_open; if (n_files <= !target_directory) { @@ -613,12 +619,14 @@ do_copy (int n_files, char **file, const char *target_directory, usage (EXIT_FAILURE); } /* Update NEW_DST and SB, which may be checked below. */ - ignore_value (target_directory_operand (file[n_files -1], &sb, &new_dst)); + ignore_value (target_directory_operand (file[n_files -1], &sb, &new_dst, + forcing)); } else if (!target_directory) { if (2 <= n_files - && target_directory_operand (file[n_files - 1], &sb, &new_dst)) + && target_directory_operand (file[n_files - 1], &sb, &new_dst, + forcing)) target_directory = file[--n_files]; else if (2 < n_files) die (EXIT_FAILURE, 0, _("target %s is not a directory"), diff --git a/tests/cp/dir-rm-dest.sh b/tests/cp/dir-rm-dest.sh index 1285b15..7de719d 100755 --- a/tests/cp/dir-rm-dest.sh +++ b/tests/cp/dir-rm-dest.sh @@ -1,5 +1,5 @@ #!/bin/sh -# verify that cp's --remove-destination option works with -R +# verify cp's --remove-destination option # Copyright (C) 2000-2018 Free Software Foundation, Inc. @@ -27,4 +27,9 @@ cp -R --remove-destination d e || fail=1 # ...and again, with an existing destination. cp -R --remove-destination d e || fail=1 +# verify no ELOOP which was the case in <= 8.29 +ln -s loop loop || framework_failure_ +touch file || framework_failure_ +cp --remove-destination file loop || fail=1 + Exit $fail diff --git a/tests/cp/thru-dangling.sh b/tests/cp/thru-dangling.sh index e16a473..8fd452e 100755 --- a/tests/cp/thru-dangling.sh +++ b/tests/cp/thru-dangling.sh @@ -27,10 +27,11 @@ echo "cp: not writing through dangling symlink 'dangle'" \ # Starting with 6.9.90, this usage fails, by default: -cp f dangle > err 2>&1 && fail=1 - -compare exp-err err || fail=1 -test -f no-such && fail=1 +for opt in '' '-f'; do + cp $opt f dangle > err 2>&1 && fail=1 + compare exp-err err || fail=1 + test -f no-such && fail=1 +done # But you can set POSIXLY_CORRECT to get the historical behavior. env POSIXLY_CORRECT=1 cp f dangle > out 2>&1 || fail=1 -- 2.9.3 --------------E15603AAF0C52AFCCA3360BF-- From debbugs-submit-bounces@debbugs.gnu.org Fri May 04 02:24:57 2018 Received: (at 31335) by debbugs.gnu.org; 4 May 2018 06:24:57 +0000 Received: from localhost ([127.0.0.1]:48800 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fEU9I-0002wn-Oa for submit@debbugs.gnu.org; Fri, 04 May 2018 02:24:57 -0400 Received: from mail-wm0-f54.google.com ([74.125.82.54]:34354) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fEU9G-0002wa-IS for 31335@debbugs.gnu.org; Fri, 04 May 2018 02:24:55 -0400 Received: by mail-wm0-f54.google.com with SMTP id a137-v6so5637174wme.1 for <31335@debbugs.gnu.org>; Thu, 03 May 2018 23:24:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=kYUUDgJE/JfJvAqW7eiBzqsntAZEFnwjsO88tr84Pu8=; b=WtLi/wHCPj3I/3uhyOqu+HqN4cgeDnH8ON5Rk6Kp4N63oW0c3k8I2MEk6NLZyFSOQm nTLObk53U8Xb6b4DoleC6oJoLFt00K8DXVycP5FS5ZbH7rMkG5hLP3DK/4qXSNAUxCIZ NyN9ijJAyDftnDO/LEeu2R9qXmvgTRXhBPnNrIIFDAoYl5yOlHvOF0LvxPplVL/Ymq3+ 2OHaRtqRkmGYjtCKYjKlZ1q8DJFqpxHIz8Ce47l/FD0Sx9sonlBNyJH+OPsl7/HHJSed AmWK64xOSr/Nv9OGNT91EtgWDKrYTjLIA/uKhv4j6QPAzCs6RBoJP+3tKOuNePKldpa3 UqNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=kYUUDgJE/JfJvAqW7eiBzqsntAZEFnwjsO88tr84Pu8=; b=lOXzhRDTCccmUDtEp6R5yH4UMQlIkDCt3UWpQ2Qhoq0UJu+gUknHYzKcfxqNs1U2Nq pS7tJrB5umGDhkU7f3MDnIsrkdT8jv2OpTMeVwDlQ+2Hb2asuKi+On7ovyt/uqpvZcwr lTdsT8HWUEr95LDrE80t2TkAIEd6XnJF/10MoxEaJufarT1mUMZhD4FhwepWeXZITvlt BPx12c5ByZmMHx/jpzohxDITYk8cCXOKbUZ+cGZa684uHefkYA0fb/uZjmBJQg9pp4ho sie9+cXAkTfX1rZPB7sdFfoBbL2W30KrW1Z3pHwvoE8CEQHmi00fc+v7pAkrjSAasV/f KSCw== X-Gm-Message-State: ALQs6tD0TMRAyXrEPkB7sg9we/Wyy4XgoAmVCCgon0v2PMZNzW5pqEUJ CIMg1EwUSlrXktrmzZoEUeleSr6ERzJgx5Mxd17zig== X-Google-Smtp-Source: AB8JxZpQbVc6RXcLjhstlELhqV1yKJ+iRzD1UQAYMVNgJUzXQwA8AoWDTBQ4EXkNt3QZgLo/GStu+qzMJf7BlDuBHi4= X-Received: by 10.28.105.15 with SMTP id e15mr15750218wmc.34.1525415088401; Thu, 03 May 2018 23:24:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.28.59.8 with HTTP; Thu, 3 May 2018 23:24:47 -0700 (PDT) In-Reply-To: References: <87tvrrckff.fsf@gmail.com> <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> From: Ernesto Alfonso Date: Thu, 3 May 2018 23:24:47 -0700 Message-ID: Subject: Fwd: bug#31335: unexpected cp -f behavior To: 31335@debbugs.gnu.org Content-Type: multipart/alternative; boundary="001a11476aee7ab43a056b5b602b" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 31335 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --001a11476aee7ab43a056b5b602b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable did not reply all ---------- Forwarded message ---------- From: Ernesto Alfonso Date: Thu, May 3, 2018 at 11:10 PM Subject: Re: bug#31335: unexpected cp -f behavior To: P=C3=A1draig Brady 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=C3=A1draig Brady 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, remov= e > 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=C3=A1draig > --001a11476aee7ab43a056b5b602b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
did not reply all

-----= ----- Forwarded message ----------
From: E= rnesto Alfonso <erjoalgo@gmail.com>
Date: Thu, May 3, 2018 at 11:10 PM=
Subject: Re: bug#31335: unexpected cp -f behavior
To: P=C3=A1draig B= rady <P@draigbrady.com>

To be honest, I think cp -f should behave consistent= ly with rm -f.

=C2=A0 =C2=A0 $ ln = -s self self
=C2=A0 =C2=A0 $ rm -f self=C2=A0
= =C2=A0 =C2=A0 $ echo $?
=C2=A0 =C2=A0 0

It's also what I would expect, if I use -f, I expect cp will do e= verything it can to force the operation and succeed if all possible.
<= div>
Reading the man page, --remove-destination and --force s= eem to just swap the cp, rm operation, i.e.

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

In either ca= se it seems that the "rm" part should correctly handle a recursiv= e symlink.

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

Thanks,
<= br>
Ernesto


<= /div>

On Thu, May = 3, 2018 at 9:30 PM, P=C3=A1draig Brady <P@draigbrady.com> wro= te:
On 01/05/18 11:14, Ernesto Alfonso wr= ote:
>
> cp -f fails when destination is a recursive symlink:
>
>=C2=A0 =C2=A0 =C2=A0$ ln -s self self
>=C2=A0 =C2=A0 =C2=A0$ cat self
>=C2=A0 =C2=A0 =C2=A0self: Too many levels of symbolic links
>=C2=A0 =C2=A0 =C2=A0$ touch a
>=C2=A0 =C2=A0 =C2=A0$ cp a self
>=C2=A0 =C2=A0 =C2=A0cp: failed to access 'self': Too many level= s of symbolic links
>=C2=A0 =C2=A0 =C2=A0$ cp -f a self
>=C2=A0 =C2=A0 =C2=A0cp: failed to access 'self': Too many level= s of symbolic links
>=C2=A0 =C2=A0 =C2=A0
>
>>From the man page:
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 -f, --force
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if=C2=A0 an=C2= =A0 existing destination file cannot be opened, remove it and try again (th= is option is ignored when
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0the -n option is= also used)

Note cp will still write through symlinks with -f.
For example with dangling symlinks one gets:
=C2=A0 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=C3=A1draig


--001a11476aee7ab43a056b5b602b-- From debbugs-submit-bounces@debbugs.gnu.org Tue May 15 13:06:01 2018 Received: (at 31335-done) by debbugs.gnu.org; 15 May 2018 17:06:01 +0000 Received: from localhost ([127.0.0.1]:35930 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIdOj-0006td-3d for submit@debbugs.gnu.org; Tue, 15 May 2018 13:06:01 -0400 Received: from mail.magicbluesmoke.com ([82.195.144.49]:42022) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIdOh-0006tW-Nm for 31335-done@debbugs.gnu.org; Tue, 15 May 2018 13:06:00 -0400 Received: from localhost.localdomain (unknown [76.21.115.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.magicbluesmoke.com (Postfix) with ESMTPSA id C579994B7; Tue, 15 May 2018 18:05:58 +0100 (IST) Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior To: Ernesto Alfonso , 31335-done@debbugs.gnu.org References: <87tvrrckff.fsf@gmail.com> <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> From: =?UTF-8?Q?P=c3=a1draig_Brady?= Message-ID: <3f747ef6-8e17-5ee1-3f3a-dcdfeace4dba@draigBrady.com> Date: Tue, 15 May 2018 10:05:56 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 31335-done X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) On 03/05/18 23:24, Ernesto Alfonso wrote: > did not reply all > > ---------- Forwarded message ---------- > From: Ernesto Alfonso > Date: Thu, May 3, 2018 at 11:10 PM > Subject: Re: bug#31335: unexpected cp -f behavior > To: PƔdraig Brady > > > 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. From debbugs-submit-bounces@debbugs.gnu.org Tue May 15 20:11:33 2018 Received: (at 31335) by debbugs.gnu.org; 16 May 2018 00:11:33 +0000 Received: from localhost ([127.0.0.1]:36121 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIk2X-0008Hh-Eh for submit@debbugs.gnu.org; Tue, 15 May 2018 20:11:33 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:35330) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIk2W-0008HU-1q for 31335@debbugs.gnu.org; Tue, 15 May 2018 20:11:32 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 42A851600CC; Tue, 15 May 2018 17:11:26 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 5q-02Dn0B0YO; Tue, 15 May 2018 17:11:25 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 82B24160104; Tue, 15 May 2018 17:11:25 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id li7WOrNXCOK9; Tue, 15 May 2018 17:11:25 -0700 (PDT) Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 68BD21600FB; Tue, 15 May 2018 17:11:25 -0700 (PDT) Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior To: 31335@debbugs.gnu.org, P@draigBrady.com, erjoalgo@gmail.com References: <87tvrrckff.fsf@gmail.com> <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> <3f747ef6-8e17-5ee1-3f3a-dcdfeace4dba@draigBrady.com> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <02d504c9-6954-2101-dae1-17bcab5f9325@cs.ucla.edu> Date: Tue, 15 May 2018 17:11:25 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: <3f747ef6-8e17-5ee1-3f3a-dcdfeace4dba@draigBrady.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 31335 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) On 05/15/2018 10:05 AM, P=C3=A1draig Brady wrote: >> It's also what I would expect, if I use -f, I expect cp will do everyt= hing >> 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=20 symlink to itself. POSIX says that if D "exists", then cp must try to=20 unlink and then re-create D; and that if D does not "exist", cp must=20 fail. So, if one considers a self-symlink as "existing", then GNU cp=20 doesn't conform to POSIX; if one considers such a symlink as not=20 "existing", then GNU cp conforms. Unfortunately, as far as I can tell=20 POSIX never exactly defines what "exists" means in this context. That being said, POSIX uses nearly the same wording for 'ln -f' that it=20 does for 'cp -f', which implies that cp should be consistent with ln,=20 and GNU ln (like most ln implementations) treat self-symlinks as=20 "existing" in this case. Also, other implementations of cp seem act like=20 ln does here, so they interpret the ambiguity in POSIX the opposite way=20 that GNU cp does. Furthermore, I think that users by and large expect=20 the non-GNU interpretation where 'cp -f' is like 'ln -f'. For all these=20 reasons, I'm inclined to think that GNU cp should fall into line here. From debbugs-submit-bounces@debbugs.gnu.org Wed May 16 03:03:06 2018 Received: (at 31335) by debbugs.gnu.org; 16 May 2018 07:03:06 +0000 Received: from localhost ([127.0.0.1]:36262 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIqSo-0006sT-DR for submit@debbugs.gnu.org; Wed, 16 May 2018 03:03:06 -0400 Received: from mail.magicbluesmoke.com ([82.195.144.49]:39344) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fIqSm-0006sJ-F9 for 31335@debbugs.gnu.org; Wed, 16 May 2018 03:03:05 -0400 Received: from localhost.localdomain (unknown [76.21.115.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.magicbluesmoke.com (Postfix) with ESMTPSA id 9488F9CED; Wed, 16 May 2018 08:03:02 +0100 (IST) Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior To: Paul Eggert , 31335@debbugs.gnu.org, erjoalgo@gmail.com References: <87tvrrckff.fsf@gmail.com> <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> <3f747ef6-8e17-5ee1-3f3a-dcdfeace4dba@draigBrady.com> <02d504c9-6954-2101-dae1-17bcab5f9325@cs.ucla.edu> From: =?UTF-8?Q?P=c3=a1draig_Brady?= Message-ID: Date: Wed, 16 May 2018 00:03:00 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <02d504c9-6954-2101-dae1-17bcab5f9325@cs.ucla.edu> Content-Type: multipart/mixed; boundary="------------1BAB788A56B5955A535ADF11" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 31335 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) This is a multi-part message in MIME format. --------------1BAB788A56B5955A535ADF11 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit 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 --------------1BAB788A56B5955A535ADF11 Content-Type: text/x-patch; name="cp-f-eloop.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="cp-f-eloop.patch" =46rom f3cf3716c70e4680f9b3ed2180c38de632c06010 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?P=3DC3=3DA1draig=3D20Brady?=3D Date: Tue, 15 May 2018 23:41:36 -0700 Subject: [PATCH] cp: with --force; replace self referential symlinks * src/copy.c (copy_internal): Don't fail immediately upon getting ELOOP when running stat() on the destination, rather proceeding if -f specified, allowing the link to be removed. If the loop is not in the final component of the destination path, we still fail but at the subsequent unlink() stage. * doc/coreutils.texi (cp invocation): Adjust wording to say that --force doesn't work with dangling links, rather than all links that can't be traversed. * tests/cp/thru-dangling.sh: Add a test case. * NEWS: Mention the change in behavior. Discussed in https://bugs.gnu.org/31335 --- NEWS | 4 ++++ doc/coreutils.texi | 2 +- src/copy.c | 7 +++++-- tests/cp/thru-dangling.sh | 13 +++++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index f981596..4c63b6d 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,10 @@ GNU coreutils NEWS = -*- outline -*- now silently does nothing if A exists. [bug introduced with coreutils-7.1] =20 +** Changes in behavior + + 'cp --force file symlink' now removes the symlink even if + it is self referential. =20 ** Improvements =20 diff --git a/doc/coreutils.texi b/doc/coreutils.texi index c8d9bd9..c28b8d0 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -8535,7 +8535,7 @@ When copying without this option and an existing de= stination file cannot be opened for writing, the copy fails. However, with @option{--force}, when a destination file cannot be opened, @command{cp} then tries to recreate the file by first removing it. Note @option{--force} -alone will not remove symlinks that can't be traversed. +alone will not remove dangling symlinks. When this option is combined with @option{--link} (@option{-l}) or @option{--symbolic-link} (@option{-s}), the destination link is replaced, and unless diff --git a/src/copy.c b/src/copy.c index 0407c56..f4c92d7 100644 --- a/src/copy.c +++ b/src/copy.c @@ -1949,12 +1949,15 @@ copy_internal (char const *src_name, char const *= dst_name, } else { - if (errno !=3D ENOENT) + if (errno =3D=3D ELOOP && x->unlink_dest_after_failed_open= ) + /* leave new_dst=3Dfalse so we unlink later. */; + else if (errno !=3D ENOENT) { error (0, errno, _("cannot stat %s"), quoteaf (dst_nam= e)); return false; } - new_dst =3D true; + else + new_dst =3D true; } } =20 diff --git a/tests/cp/thru-dangling.sh b/tests/cp/thru-dangling.sh index 8fd452e..e433525 100755 --- a/tests/cp/thru-dangling.sh +++ b/tests/cp/thru-dangling.sh @@ -28,15 +28,24 @@ echo "cp: not writing through dangling symlink 'dangl= e'" \ =20 # Starting with 6.9.90, this usage fails, by default: for opt in '' '-f'; do - cp $opt f dangle > err 2>&1 && fail=3D1 + returns_ 1 cp $opt f dangle > err 2>&1 || fail=3D1 compare exp-err err || fail=3D1 test -f no-such && fail=3D1 done =20 + # But you can set POSIXLY_CORRECT to get the historical behavior. env POSIXLY_CORRECT=3D1 cp f dangle > out 2>&1 || fail=3D1 cat no-such >> out || fail=3D1 - compare exp out || fail=3D1 =20 + +# Starting with 8.30 we treat ELOOP as existing and so +# remove the symlink +ln -s loop loop || framework_failure_ +cp -f f loop > err 2>&1 || fail=3D1 +compare /dev/null err || fail=3D1 +compare exp loop || fail=3D1 +test -f loop || fail=3D1 + Exit $fail --=20 2.9.3 --------------1BAB788A56B5955A535ADF11-- From debbugs-submit-bounces@debbugs.gnu.org Thu May 17 23:54:10 2018 Received: (at 31335) by debbugs.gnu.org; 18 May 2018 03:54:10 +0000 Received: from localhost ([127.0.0.1]:39030 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fJWT3-0003NH-Vk for submit@debbugs.gnu.org; Thu, 17 May 2018 23:54:10 -0400 Received: from mail.magicbluesmoke.com ([82.195.144.49]:47020) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fJWT1-0003N8-KU for 31335@debbugs.gnu.org; Thu, 17 May 2018 23:54:08 -0400 Received: from localhost.localdomain (unknown [76.21.115.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.magicbluesmoke.com (Postfix) with ESMTPSA id EAE48A8D5; Fri, 18 May 2018 04:54:05 +0100 (IST) Subject: Re: bug#31335: Fwd: bug#31335: unexpected cp -f behavior To: 31335@debbugs.gnu.org, erjoalgo@gmail.com References: <87tvrrckff.fsf@gmail.com> <1270c6eb-3e5f-4054-f38e-635d23cc9109@draigBrady.com> <3f747ef6-8e17-5ee1-3f3a-dcdfeace4dba@draigBrady.com> <02d504c9-6954-2101-dae1-17bcab5f9325@cs.ucla.edu> From: =?UTF-8?Q?P=c3=a1draig_Brady?= Message-ID: <799b2c51-2c2a-35ee-6880-dfaf6591e6fc@draigBrady.com> Date: Thu, 17 May 2018 20:54:03 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 31335 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) 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 From unknown Sat Aug 09 13:01:20 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Fri, 15 Jun 2018 11:24:07 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator