* NEWS, doc/coreutils.texi: Document this.
* src/copy.c (copy_internal):
* src/ln.c (do_link): Return false when skipping action due to
--interactive or --no-clobber.
* tests/cp/cp-i.sh, tests/cp/preserve-link.sh:
* tests/cp/slink-2-slink.sh, tests/mv/i-1.pl, tests/mv/i-5.sh:
* tests/mv/mv-n.sh, tests/mv/update.sh:
Adjust expectations of exit status to match revised behavior.
'cp --reflink=always A B' no longer leaves behind a newly created
empty file B merely because copy-on-write clones are not supported.
+ 'cp -n' and 'mv -n' now exit with nonzero status if they skip their
+ action because the destination exists, and likewise for 'cp -i',
+ 'ln -i', and 'mv -i' when the user declines. (POSIX specifies this
+ for 'cp -i' and 'mv -i'.)
+
cp, mv, and install again read in multiples of the reported block size,
to support unusual devices that may have this constraint.
[behavior inadvertently changed in coreutils-7.2]
@opindex -i
@opindex --interactive
When copying a file other than a directory, prompt whether to
-overwrite an existing destination file. The @option{-i} option overrides
+overwrite an existing destination file, and fail if the response
+is not affirmative. The @option{-i} option overrides
a previous @option{-n} option.
@item -l
@itemx --no-clobber
@opindex -n
@opindex --no-clobber
-Do not overwrite an existing file; silently do nothing instead.
+Do not overwrite an existing file; silently fail instead.
This option overrides a previous
@option{-i} option. This option is mutually exclusive with @option{-b} or
@option{--backup} option.
@opindex --update
@cindex newer files, copying only
Do not copy a non-directory that has an existing destination with the
-same or newer modification timestamp. If timestamps are being preserved,
+same or newer modification timestamp; silently fail instead.
+If timestamps are being preserved,
the comparison is to the source timestamp truncated to the
resolutions of the destination file system and of the system calls
used to update timestamps; this avoids duplicate work if several
@opindex --interactive
@cindex prompts, forcing
Prompt whether to overwrite each existing destination file, regardless
-of its permissions.
-If the response is not affirmative, the file is skipped.
+of its permissions, and fail if the response is not affirmative.
@mvOptsIfn
@item -n
@opindex -n
@opindex --no-clobber
@cindex prompts, omitting
-Do not overwrite an existing file; silently do nothing instead.
+Do not overwrite an existing file; silently fail instead.
@mvOptsIfn
This option is mutually exclusive with @option{-b} or @option{--backup} option.
@opindex --update
@cindex newer files, moving only
Do not move a non-directory that has an existing destination with the
-same or newer modification timestamp.
+same or newer modification timestamp; silently fail instead.
If the move is across file system boundaries, the comparison is to the
source timestamp truncated to the resolutions of the destination file
system and of the system calls used to update timestamps; this avoids
@item -i
@opindex -i
Prompt whether to remove each file.
-If the response is not affirmative, the file is skipped.
+If the response is not affirmative, silently skip the file without failing.
Ignore any previous @option{--force} (@option{-f}) option.
Equivalent to @option{--interactive=always}.
@item --one-file-system
@opindex --one-file-system
@cindex one file system, restricting @command{rm} to
-When removing a hierarchy recursively, skip any directory that is on a
+When removing a hierarchy recursively, do not remove any directory that is on a
file system different from that of the corresponding command line argument.
@cindex bind mount
This option is useful when removing a build ``chroot'' hierarchy,
your normally throw-away chroot, that command will remove everything
under @file{/home}, too.
Use the @option{--one-file-system} option, and it will
-warn about and skip directories on other file systems.
+diagnose and skip directories on other file systems.
Of course, this will not save your @file{/home} if it and your
chroot happen to be on the same file system.
See also @option{--preserve-root=all} to protect command line arguments
@opindex -i
@opindex --interactive
@cindex prompting, and @command{ln}
-Prompt whether to remove existing destination files.
+Prompt whether to remove existing destination files,
+and fail if the response is not affirmative.
@item -L
@itemx --logical
}
}
- return true;
+ return false;
}
}
doesn't end up removing the source file. */
if (rename_succeeded)
*rename_succeeded = true;
- return true;
+ return false;
}
}
else
|| (x->interactive == I_ASK_USER
&& ! overwrite_ok (x, dst_name, dst_dirfd,
dst_relname, &dst_sb))))
- return true;
+ return false;
}
if (return_now)
if (!yesno ())
{
free (rel_source);
- return true;
+ return false;
}
}
# coreutils 6.2 cp would neglect to prompt in this case.
-echo n | cp -iR a b 2>/dev/null || fail=1
+echo n | returns_ 1 cp -iR a b 2>/dev/null || fail=1
# test miscellaneous combinations of -f -i -n parameters
touch c d || framework_failure_
> out_empty
# ask for overwrite, answer no
-echo n | cp -vi c d 2>/dev/null > out1 || fail=1
+echo n | returns_ 1 cp -vi c d 2>/dev/null > out1 || fail=1
compare out1 out_empty || fail=1
# ask for overwrite, answer yes
compare out3 out_copy || fail=1
# -n wins over -i
-echo y | cp -vin c d 2>/dev/null > out4 || fail=1
+echo y | returns_ 1 cp -vin c d 2>/dev/null > out4 || fail=1
compare out4 out_empty || fail=1
# ask for overwrite, answer yes
compare out5 out_copy || fail=1
# do not ask, prevent from overwrite
-echo n | cp -vfn c d 2>/dev/null > out6 || fail=1
+echo n | returns_ 1 cp -vfn c d 2>/dev/null > out6 || fail=1
compare out6 out_empty || fail=1
# do not ask, prevent from overwrite
-echo n | cp -vnf c d 2>/dev/null > out7 || fail=1
+echo n | returns_ 1 cp -vnf c d 2>/dev/null > out7 || fail=1
compare out7 out_empty || fail=1
# options --backup and --no-clobber are mutually exclusive
# Copy all the hard links across. With cp from coreutils-8.12
# and prior, it would sometimes mistakenly copy rather than link.
- cp -au s t || fail=1
+ returns_ 1 cp -au s t || fail=1
same_inode t/s/f t/s/linkm || fail=1
same_inode t/s/f t/s/linke || fail=1
ln -s no-such-file c || framework_failure_
ln -s no-such-file d || framework_failure_
-cp --update --no-dereference a b || fail=1
-cp --update --no-dereference c d || fail=1
+returns_ 1 cp --update --no-dereference a b || fail=1
+returns_ 1 cp --update --no-dereference c d || fail=1
Exit $fail
{IN => {src => "a\n"}}, {IN => {dst => "b\n"}}, '<', {IN => "n\n"},
{ERR => "mv: overwrite 'dst'? "},
{POST => sub { -r 'src' or die "test $test_a failed\n"}},
- {EXIT => 0},
+ {EXIT => 1},
],
);
# coreutils 6.2 mv would neglect to prompt in this case.
-echo n | mv -i a b 2>/dev/null || fail=1
+echo n | returns_ 1 mv -i a b 2>/dev/null || fail=1
Exit $fail
# ask for overwrite, answer no
touch a b || framework_failure_
-echo n | mv -vi a b 2>/dev/null > out1 || fail=1
+echo n | returns_ 1 mv -vi a b 2>/dev/null > out1 || fail=1
compare out1 out_empty || fail=1
# ask for overwrite, answer yes
# -n wins (as the last option)
touch a b || framework_failure_
-echo y | mv -vin a b 2>/dev/null > out3 || fail=1
+echo y | returns_ 1 mv -vin a b 2>/dev/null > out3 || fail=1
compare out3 out_empty || fail=1
# -n wins (as the last option)
touch a b || framework_failure_
-echo y | mv -vfn a b 2>/dev/null > out4 || fail=1
+echo y | returns_ 1 mv -vfn a b 2>/dev/null > out4 || fail=1
compare out4 out_empty || fail=1
# -n wins (as the last option)
touch a b || framework_failure_
-echo y | mv -vifn a b 2>/dev/null > out5 || fail=1
+echo y | returns_ 1 mv -vifn a b 2>/dev/null > out5 || fail=1
compare out5 out_empty || fail=1
# options --backup and --no-clobber are mutually exclusive
# This is a no-op, with no prompt.
# With coreutils-6.9 and earlier, using --update with -i would
# mistakenly elicit a prompt.
- $cp_or_mv $interactive --update old new < /dev/null > out 2>&1 || fail=1
+ returns_ 1 $cp_or_mv $interactive --update old new </dev/null >out 2>&1 ||
+ fail=1
compare /dev/null out || fail=1
case "$(cat new)" in new) ;; *) fail=1 ;; esac
case "$(cat old)" in old) ;; *) fail=1 ;; esac