diff options
author | Jim Meyering <jim@meyering.net> | 2005-03-11 09:36:52 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2005-03-11 09:36:52 +0000 |
commit | d0f21b4a5583235001aaac254efc0802de414eec (patch) | |
tree | 706ad85397b060e1294b8c82d7b3e165897ef924 /src/copy.c | |
parent | d1d993432f0a4460e426b32e6442e0bded14ece0 (diff) | |
download | coreutils-d0f21b4a5583235001aaac254efc0802de414eec.tar.xz |
Prompt once again for `mv -i A B' when A and B are hard links
to the same file. This fixes a bug introduced by my 2003-04-04
(coreutils-5.0.1) change.
(abandon_move): New function, factored out of
copy_internal, now that this code is being used from two places.
(copy_internal): Perform the same interactive-related test for
whether it's alright to proceed and (usually) overwrite the
destination file.
Diffstat (limited to 'src/copy.c')
-rw-r--r-- | src/copy.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/copy.c b/src/copy.c index 62cf4ec6e..88df1d4b3 100644 --- a/src/copy.c +++ b/src/copy.c @@ -792,6 +792,28 @@ record_file (Hash_table *ht, char const *filename, } } +/* When effecting a move (e.g., for mv(1)), and given the name DST_PATH + of the destination and a corresponding stat buffer, DST_SB, return + true if the logical `move' operation should not proceed. + Return true if it may proceed. + Depending on options specified in X, this code may issue an + interactive prompt asking whether it's ok to overwrite DST_PATH. */ +static bool +abandon_move (const struct cp_options *x, + char const *dst_path, + struct stat const *dst_sb) +{ + assert (x->move_mode); + return ((x->interactive == I_ALWAYS_NO + && UNWRITABLE (dst_path, dst_sb->st_mode)) + || ((x->interactive == I_ASK_USER + || (x->interactive == I_UNSPECIFIED + && x->stdin_tty + && UNWRITABLE (dst_path, dst_sb->st_mode))) + && (overwrite_prompt (dst_path, dst_sb), 1) + && ! yesno ())); +} + /* Copy the file SRC_PATH to the file DST_PATH. The files may be of any type. NEW_DST should be true if the file DST_PATH cannot exist because its parent directory was just created; NEW_DST should @@ -887,7 +909,8 @@ copy_internal (const char *src_path, const char *dst_path, x, &return_now, &unlink_src); if (unlink_src) { - if (unlink (src_path)) + if (!abandon_move (x, dst_path, &dst_sb) + && unlink (src_path)) { error (0, errno, _("cannot remove %s"), quote (src_path)); return false; @@ -980,14 +1003,7 @@ copy_internal (const char *src_path, const char *dst_path, /* cp and mv treat -i and -f differently. */ if (x->move_mode) { - if ((x->interactive == I_ALWAYS_NO - && UNWRITABLE (dst_path, dst_sb.st_mode)) - || ((x->interactive == I_ASK_USER - || (x->interactive == I_UNSPECIFIED - && x->stdin_tty - && UNWRITABLE (dst_path, dst_sb.st_mode))) - && (overwrite_prompt (dst_path, &dst_sb), 1) - && ! yesno ())) + if (abandon_move (x, dst_path, &dst_sb)) { /* Pretend the rename succeeded, so the caller (mv) doesn't end up removing the source file. */ |