summaryrefslogtreecommitdiff
path: root/src/copy.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-05-29 21:05:07 +0000
committerJim Meyering <jim@meyering.net>2000-05-29 21:05:07 +0000
commitf06a2374fd72f0211eaf432688b28bf9d537c2be (patch)
treed493336a58d1fce3ef478884fa14d5f5dfcaeede /src/copy.c
parentff9eb128094af34b8a8dfaea4b6572504e261e5a (diff)
downloadcoreutils-f06a2374fd72f0211eaf432688b28bf9d537c2be.tar.xz
Allow `cp -d -u' to copy one symlink onto another that's identical.
(copy_internal): Change the || to ^ in the big sameness test, so copying one symlink onto another, identical one doesn't fail here. If the symlink call fails, don't report the failure if the destination already exists and is a symlink pointing to the proper name.
Diffstat (limited to 'src/copy.c')
-rw-r--r--src/copy.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/copy.c b/src/copy.c
index 48b4d2268..32f5e5bdc 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -448,7 +448,7 @@ copy_internal (const char *src_path, const char *dst_path,
&& S_ISLNK (src_sb.st_mode)
&& !S_ISLNK (dst_sb.st_mode)))
&& !x->dereference
- && (S_ISLNK (dst_sb.st_mode) || S_ISLNK (src_sb.st_mode)))
+ && (S_ISLNK (dst_sb.st_mode) ^ S_ISLNK (src_sb.st_mode)))
{
struct stat dst2_sb;
struct stat src2_sb;
@@ -848,8 +848,28 @@ copy_internal (const char *src_path, const char *dst_path,
if (symlink (link_val, dst_path))
{
- error (0, errno, _("cannot create symbolic link `%s'"), dst_path);
- goto un_backup;
+ int saved_errno = errno;
+ int same_link = 0;
+ if (x->update && !new_dst && S_ISLNK (dst_sb.st_mode))
+ {
+ /* See if the destination is already the desired symlink. */
+ char *dest_link_name = (char *) alloca (PATH_MAX + 2);
+ int dest_link_len = readlink (dst_path, dest_link_name,
+ PATH_MAX + 1);
+ if (dest_link_len > 0)
+ {
+ dest_link_name[dest_link_len] = '\0';
+ if (STREQ (dest_link_name, link_val))
+ same_link = 1;
+ }
+ }
+
+ if (! same_link)
+ {
+ error (0, saved_errno, _("cannot create symbolic link `%s'"),
+ dst_path);
+ goto un_backup;
+ }
}
if (x->preserve_owner_and_group)