diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2007-06-15 22:47:16 +0200 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2007-06-15 22:47:16 +0200 |
commit | cdec7e6e93db547a80525c24167345a090a00273 (patch) | |
tree | ca98ab8f400d602f30f1642fb1ff8b57c9713b25 /src/cp.c | |
parent | cad884a24545464cb42296834a8b5c02ee116379 (diff) | |
download | coreutils-cdec7e6e93db547a80525c24167345a090a00273.tar.xz |
Correct cp's handling of destination symlinks in some cases.
* NEWS: "cp" no longer considers a destination symlink to be the
same as the referenced file when copying links or making backups.
* src/copy.c (copy_reg): When following a symlink, use the
followed name in later chown etc. requests, so that the created
file is affected, rather than the symlink. Use O_NOFOLLOW on
source when not dereferencing symlinks; this avoids a race.
Preserve errno correctly when doing multiple open attempts on the
destination.
(copy_internal): Follow destination symlinks only when copying a
regular file and only when we don't intend to remove or rename the
destination first, regardless of whether following source
symlinks; this is because since POSIX and tradition (e.g.,
FreeBSD) say we should ordinarily follow destination symlinks if
the system calls would ordinarily do so.
* src/copy.h (struct cp_options): Add comment that 'dereference'
is only for source files.
* src/cp.c (usage): Note that --derereference etc. are only for
source files.
(make_dir_parents_private): Follow symlinks, regardless of whether
--dereference is specified, because these are destination symlinks.
* tests/cp/same-file: Adjust tests to match revised behavior.
Filter out perror output since it might vary from host to host.
Use sed alone instead of also using echo.
* doc/coreutils.texi (cp invocation): Document the behavior better when
the destination is a symlink. Clarify source versus destination
symlinks. Describe the new behavior for destination symlinks.
2007-06-15 Jim Meyering <jim@meyering.net>
* src/copy.c: Include "canonicalize.h".
(copy_reg): Use canonicalize_filename_mode to follow the symlink,
so that we can always open with O_EXCL and avoid a race.
Diffstat (limited to 'src/cp.c')
-rw-r--r-- | src/cp.c | 12 |
1 files changed, 6 insertions, 6 deletions
@@ -181,14 +181,14 @@ Mandatory arguments to long options are mandatory for short options too.\n\ -f, --force if an existing destination file cannot be\n\ opened, remove it and try again\n\ -i, --interactive prompt before overwrite\n\ - -H follow command-line symbolic links\n\ + -H follow command-line symbolic links in SOURCE\n\ "), stdout); fputs (_("\ -l, --link link files instead of copying\n\ - -L, --dereference always follow symbolic links\n\ + -L, --dereference always follow symbolic links in SOURCE\n\ "), stdout); fputs (_("\ - -P, --no-dereference never follow symbolic links\n\ + -P, --no-dereference never follow symbolic links in SOURCE\n\ "), stdout); fputs (_("\ -p same as --preserve=mode,ownership,timestamps\n\ @@ -393,7 +393,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, *attr_list = NULL; - if (XSTAT (x, dst_dir, &stats)) + if (stat (dst_dir, &stats) != 0) { /* A parent of CONST_DIR does not exist. Make all missing intermediate directories. */ @@ -413,7 +413,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, *attr_list = new; *slash = '\0'; - if (XSTAT (x, dir, &stats)) + if (stat (dir, &stats) != 0) { mode_t src_mode; mode_t omitted_permissions; @@ -426,7 +426,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, make_dir_parents_private creates only e_dir/../a if ./b already exists. */ *new_dst = true; - src_errno = (XSTAT (x, src, &stats) != 0 + src_errno = (stat (src, &stats) != 0 ? errno : S_ISDIR (stats.st_mode) ? 0 |