summaryrefslogtreecommitdiff
path: root/src/cp.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2007-06-15 22:47:16 +0200
committerJim Meyering <jim@meyering.net>2007-06-15 22:47:16 +0200
commitcdec7e6e93db547a80525c24167345a090a00273 (patch)
treeca98ab8f400d602f30f1642fb1ff8b57c9713b25 /src/cp.c
parentcad884a24545464cb42296834a8b5c02ee116379 (diff)
downloadcoreutils-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.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/cp.c b/src/cp.c
index 3023408db..1d66bc382 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -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