diff options
author | Jim Meyering <jim@meyering.net> | 2006-06-03 09:04:22 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-06-03 09:04:22 +0000 |
commit | 4c7979f7c249606c0d6b73fd01b92b0825d83741 (patch) | |
tree | 8ddc8281638f90c238886684d1248e4d8649ecc2 /src | |
parent | 6293c4ae503c59411e8f2f66e91149a47829fbd9 (diff) | |
download | coreutils-4c7979f7c249606c0d6b73fd01b92b0825d83741.tar.xz |
Make `cp --link --no-dereference' work also on systems where the
link system call cannot create a hard link to a symbolic link.
(copy_internal) [LINK_FOLLOWS_SYMLINKS]: Don't use
the link syscall on a symlink when it would do the wrong thing.
Based on the patch by Aurelien Jarno: <http://bugs.debian.org/329451>
Diffstat (limited to 'src')
-rw-r--r-- | src/copy.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/copy.c b/src/copy.c index a6f6ec54e..a6ea3e6b6 100644 --- a/src/copy.c +++ b/src/copy.c @@ -1594,7 +1594,22 @@ copy_internal (char const *src_name, char const *dst_name, } } #endif - else if (x->hard_link) + + else if (x->hard_link +#ifdef LINK_FOLLOWS_SYMLINKS + /* A POSIX-conforming link syscall dereferences a symlink, yet cp, + invoked with `--link --no-dereference', should not. Thus, with + a POSIX-conforming link system call, we can't use link() here, + since that would create a hard link to the referent (effectively + dereferencing the symlink), rather than to the symlink itself. + We can approximate the desired behavior by skipping this hard-link + creating block and instead copying the symlink, via the `S_ISLNK'- + copying code below. + When link operates on the symlinks themselves, we use this block + and just call link(). */ + && !(S_ISLNK (src_mode) && x->dereference == DEREF_NEVER) +#endif + ) { preserve_metadata = false; if (link (src_name, dst_name)) |