From 376967889ed7ed561e46ff6d88a66779db62737a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 11 Feb 2017 23:12:31 -0800 Subject: ln: replace destination links more atomically If the file B already exists, commands like 'ln -f A B' and 'cp -fl A B' no longer remove B before creating the new link. Instead, they arrange for the new link to replace B atomically. This should fix a race condition reported by Mike Crowe (Bug#25680). * NEWS, doc/coreutils.texi (cp invocation, ln invocation): Document this. * bootstrap.conf (gnulib_modules): Add symlinkat. * src/copy.c, src/ln.c: Include force-link.h. * src/copy.c (same_file_ok): It's also OK to remove a destination symlink when creating symbolic links, or when the source and destination are on the same file system and when creating hard links. * src/copy.c (create_hard_link, copy_internal): * src/ln.c (do_link): Rewrite using force_linkat and force_symlinkat, to close a window where the destination temporarily does not exist. * src/cp.c (main): Do not set x.unlink_dest_before_opening merely because we are in link-creation mode. * src/force-link.c, src/force-link.h: New files. * src/local.mk (copy_sources, src_ln_SOURCES): Add them. * tests/cp/same-file.sh: Adjust test case to match fixed behavior. --- tests/cp/same-file.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/cp/same-file.sh') diff --git a/tests/cp/same-file.sh b/tests/cp/same-file.sh index 978bba81b..9aa6a2112 100755 --- a/tests/cp/same-file.sh +++ b/tests/cp/same-file.sh @@ -142,7 +142,7 @@ cat <<\EOF | sed "$remove_these_sed" > expected 0 -bf (foo symlink symlink.~1~ -> foo) 0 -bdf (foo symlink symlink.~1~ -> foo) 1 -l [cp: cannot create hard link 'symlink' to 'foo'] (foo symlink -> foo) -0 -dl (foo symlink -> foo) +1 -dl [cp: cannot create hard link 'symlink' to 'foo'] (foo symlink -> foo) 0 -fl (foo symlink) 0 -dfl (foo symlink) 0 -bl (foo symlink symlink.~1~ -> foo) -- cgit v1.2.3-54-g00ecf