mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-08-14 22:19:02 +02:00
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.
This commit is contained in:
+23
-3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user