From 51d42245674dc864ac0dbb2f160a55cd38fc2458 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Fri, 4 May 2018 09:41:27 -0700 Subject: [PATCH 2/2] cp: Overwrite symlinks on another device When target of a copy operation is a symlink, it is not the same file as the source, so it is safe to overwrite it, regardless of if it is the same device as the source or a different device. Previous check only allowed overwrite on the same device and produced an error when run across different file systems. --- src/copy.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/copy.c b/src/copy.c index dbfabf215..b35f9568b 100644 --- a/src/copy.c +++ b/src/copy.c @@ -1627,11 +1627,16 @@ same_file_ok (char const *src_name, struct stat const *src_sb, } } - /* It's ok to remove a destination symlink. But that works only - when creating symbolic links, or when the source and destination - are on the same file system and creating hard links. */ - if (x->symbolic_link - || (x->hard_link && S_ISLNK (dst_sb_link->st_mode))) + /* It's ok to remove a destination symlink - does not affect the source. */ + if (x->symbolic_link) + return true; + + /* When creating hard links it OK when the source and destination are on the + same file system. TODO: The S_ISLNK() check is probably redundant, as we + should not be here if the source and the destination are the same file and + the destination is not a symbolic link. The case when the source and the + destination are the same due to being hard links is checked above. */ + if (x->hard_link && S_ISLNK (dst_sb_link->st_mode)) return dst_sb_link->st_dev == src_sb_link->st_dev; if (x->dereference == DEREF_NEVER) -- 2.17.0.441.gb46fe60e1d-goog