mv -n: do not overwrite the destination
This commit is contained in:
parent
4de12df039
commit
70bc76ac6c
|
@ -0,0 +1,63 @@
|
|||
From 76df06ff8fa39ae0cb0d167b7f622139778dc7d7 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Thu, 4 Jan 2018 09:42:10 +0100
|
||||
Subject: [PATCH] mv -n: do not overwrite the destination
|
||||
|
||||
... if it is created by another process after mv has checked its
|
||||
non-existence.
|
||||
|
||||
* src/copy.c (copy_internal): Use renameat2 (..., RENAME_NOREPLACE)
|
||||
if called by mv -n. If it fails with EEXIST in that case, pretend
|
||||
successful rename as if the existing destination file was detected
|
||||
by the preceding lstat call.
|
||||
|
||||
Fixes https://bugs.gnu.org/29961
|
||||
---
|
||||
src/copy.c | 17 ++++++++++++++++-
|
||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/copy.c b/src/copy.c
|
||||
index 2a804945e..be4e357a8 100644
|
||||
--- a/src/copy.c
|
||||
+++ b/src/copy.c
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "ignore-value.h"
|
||||
#include "ioblksize.h"
|
||||
#include "quote.h"
|
||||
+#include "renameat2.h"
|
||||
#include "root-uid.h"
|
||||
#include "same.h"
|
||||
#include "savedir.h"
|
||||
@@ -2312,7 +2313,12 @@ copy_internal (char const *src_name, char const *dst_name,
|
||||
|
||||
if (x->move_mode)
|
||||
{
|
||||
- if (rename (src_name, dst_name) == 0)
|
||||
+ int flags = 0;
|
||||
+ if (x->interactive == I_ALWAYS_NO)
|
||||
+ /* do not replace DST_NAME if it was created since our last check */
|
||||
+ flags = RENAME_NOREPLACE;
|
||||
+
|
||||
+ if (renameat2 (AT_FDCWD, src_name, AT_FDCWD, dst_name, flags) == 0)
|
||||
{
|
||||
if (x->verbose && S_ISDIR (src_mode))
|
||||
emit_verbose (src_name, dst_name,
|
||||
@@ -2342,6 +2348,15 @@ copy_internal (char const *src_name, char const *dst_name,
|
||||
return true;
|
||||
}
|
||||
|
||||
+ if ((flags & RENAME_NOREPLACE) && (errno == EEXIST))
|
||||
+ {
|
||||
+ /* Pretend the rename succeeded, so the caller (mv)
|
||||
+ doesn't end up removing the source file. */
|
||||
+ if (rename_succeeded)
|
||||
+ *rename_succeeded = true;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
/* FIXME: someday, consider what to do when moving a directory into
|
||||
itself but when source and destination are on different devices. */
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 8.27
|
||||
Release: 17%{?dist}
|
||||
Release: 18%{?dist}
|
||||
License: GPLv3+
|
||||
Group: System Environment/Base
|
||||
Url: https://www.gnu.org/software/coreutils/
|
||||
|
@ -31,6 +31,10 @@ Patch5: coreutils-8.27-ptx-int-overflow.patch
|
|||
# df: do not call stat() on file system unless it is necessary (#1511951)
|
||||
Patch6: coreutils-8.27-df-stat.patch
|
||||
|
||||
# mv -n: do not overwrite the destination, superseded by
|
||||
# http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=v8.29-9-g29baf25aa
|
||||
Patch7: coreutils-8.29-mv-n-noreplace.patch
|
||||
|
||||
# disable the test-lock gnulib test prone to deadlock
|
||||
Patch100: coreutils-8.26-test-lock.patch
|
||||
|
||||
|
@ -299,6 +303,9 @@ fi
|
|||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Tue Jan 23 2018 Kamil Dudka <kdudka@redhat.com> - 8.27-18
|
||||
- mv -n: do not overwrite the destination
|
||||
|
||||
* Fri Nov 10 2017 Kamil Dudka <kdudka@redhat.com> - 8.27-17
|
||||
- df: do not call stat() on file system unless it is necessary (#1511951)
|
||||
|
||||
|
|
Loading…
Reference in New Issue