bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#7450: cp does not check for errno=EISDIR when target is dangling lin


From: Paul Eggert
Subject: bug#7450: cp does not check for errno=EISDIR when target is dangling link
Date: Sun, 21 Nov 2010 18:54:03 -0800
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6

On 11/21/2010 01:49 AM, Jim Meyering wrote:
>   ./cp: invalid destination: `no-such/'
>   a destination with a trailing slash must refer to an existing directory

In addition to the problem with mv that Alan mentions,
this diagnostic is still confusing, at least for me.  Also, what's
the relationship of this to the -t and -T options?  Currently we have this
behavior when the destination exists:

   $ cp a /usr/
   cp: cannot create regular file `/usr/a': Permission denied
   $ cp a -t /usr/
   cp: cannot create regular file `/usr/a': Permission denied
   $ cp -T a /usr/
   cp: cannot overwrite directory `/usr/' with non-directory

Wouldn't the change cause these diagnostics to be confusing if
we replace /usr with /nosuch?

How about this idea instead.  Simply replace the bogus errno value
with a better one.  Then, we'd see this behavior:

   $ cp a /nosuch/
   cp: cannot create regular file `/nosuch/': Not a directory
   $ cp a -t /nosuch/
   cp: accessing `/nosuch/': No such file or directory
   $ cp -T a /nosuch/
   cp: cannot create regular file `/nosuch/': Not a directory

These messages are perhaps not ideal, but they're good enough,
and fit better into the existing message style.
Here's a proposed patch to do that.  (By the way, the kernel is
entirely within its rights to generate EISDIR: when there are
multiple errors to report, the kernel can report any of the errno
values.)


>From 9d637cb3e052a529b5c7ec5e7ce70931436a3c45 Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Sun, 21 Nov 2010 18:50:41 -0800
Subject: [PATCH] cp: give a better diagnostic for nonexistent dest/
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch was written by Jim Meyering and myself.
* src/copy.c (copy_reg): Turn EISDIR to ENOTDIR to improve the
quality of diagnostics for commands like "cp a nosuch/".  Reported
by Марк Коренберг and Alan Curry in the thread starting at:
http://lists.gnu.org/archive/html/bug-coreutils/2010-11/msg00178.html
* THANKS: Update.
* tests/mv/trailing-slash: Add a test.
---
 THANKS                  |    1 +
 src/copy.c              |    6 ++++++
 tests/mv/trailing-slash |    8 ++++++++
 3 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/THANKS b/THANKS
index 0123c32..9bd78c8 100644
--- a/THANKS
+++ b/THANKS
@@ -362,6 +362,7 @@ M. P. Suzuki                        address@hidden
 Maciej Kwapulinski                  address@hidden
 Manas Garg                          address@hidden
 Manfred Hollstein                   address@hidden
+Марк Коренберг                      address@hidden
 Marc Boucher                        address@hidden
 Marc Haber                          address@hidden
 Marc Lehman                         address@hidden
diff --git a/src/copy.c b/src/copy.c
index 07501df..42d6d92 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -603,6 +603,12 @@ copy_reg (char const *src_name, char const *dst_name,
                 }
             }
         }
+
+      /* Improve quality of diagnostic when a nonexistent dst_name
+         ends in a slash and open fails with errno == EISDIR.  */
+      if (dest_desc < 0 && dest_errno == EISDIR
+          && *dst_name && dst_name[strlen (dst_name) - 1] == '/')
+        dest_errno = ENOTDIR;
     }
   else
     omitted_permissions = 0;
diff --git a/tests/mv/trailing-slash b/tests/mv/trailing-slash
index b58c908..906174a 100755
--- a/tests/mv/trailing-slash
+++ b/tests/mv/trailing-slash
@@ -50,4 +50,12 @@ done
 #touch a a2
 #mv a a2/ && fail=1
 
+# Test for a cp-specific diagnostic introduced after coreutils-8.7:
+printf '%s\n' \
+  "cp: cannot create regular file \`no-such/': Not a directory" \
+> expected-err
+touch b
+cp b no-such/ 2> err && fail=1
+compare err expected-err || fail=1
+
 Exit $fail
-- 
1.7.2






reply via email to

[Prev in Thread] Current Thread [Next in Thread]