+2007-02-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: Document fix for cp --parents.
+ * src/cp.c (make_dir_parents_private): Report the error sooner with
+ "cp --parents DIR/FILE DEST" when DIR is a non-directory, thus not
+ creating the directory, DEST/DIR.
+ * tests/cp/cp-parents: Test for the non-race-condition bug fixed
+ by the above change.
+
2007-02-02 Jim Meyering <jim@meyering.net>
* src/nl.c (proc_text): Use "NULL", not "(struct re_registers *) 0".
chmod no longer fails in an environment (e.g., a chroot) with openat
support but with insufficient /proc support.
+ "cp --parents F/G D" no longer creates a directory D/F when F is not
+ a directory (and F/G is therefore invalid).
+
cut no longer dumps core for usage like "cut -f2- f1 f2" with two or
more file arguments. This was due to a double-free bug, introduced
in coreutils-5.3.0.
/* cp.c -- file copying (main routines)
- Copyright (C) 89, 90, 91, 1995-2006 Free Software Foundation.
+ Copyright (C) 89, 90, 91, 1995-2007 Free Software Foundation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
mode_t src_mode;
mode_t omitted_permissions;
mode_t mkdir_mode;
+ int src_errno;
/* This component does not exist. We must set
*new_dst and new->mode inside this loop because,
make_dir_parents_private creates only e_dir/../a if
./b already exists. */
*new_dst = true;
- if (XSTAT (x, src, &stats))
+ src_errno = (XSTAT (x, src, &stats) != 0
+ ? errno
+ : S_ISDIR (stats.st_mode)
+ ? 0
+ : ENOTDIR);
+ if (src_errno)
{
- error (0, errno, _("failed to get attributes of %s"),
+ error (0, src_errno, _("failed to get attributes of %s"),
quote (src));
return false;
}
# cp -R --parents dir-specified-with-trailing-slash/ other-dir
# would get a failed assertion.
-# Copyright (C) 2000, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2002, 2004, 2005, 2006, 2007 Free Software
+# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
mkdir foo bar || framework_failure=1
mkdir -p a/b/c d e || framework_failure=1
+touch f || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework'
cp --verbose -a --parents a/b/c d > /dev/null 2>&1 || fail=1
test -d d/a/b/c || fail=1
+# With 6.7 and earlier, cp --parents f/g d would mistakenly create a
+# directory d/f, even though f is a regular file.
+cp --parents f/g d 2>/dev/null && fail=1
+test -d d/f && fail=1
+
# Check that re_protect works.
chmod go=w d/a
cp -a --parents d/a/b/c e || fail=1