mv: use RENAME_NOREPLACE
when we can
#7832
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #7791. This currently fails to build with cross, because the release version of cross uses ancient Ubuntu 16.04 images, which ship glibc 2.23, while
renameat2
support was added in glibc 2.28. We could fix this now by using a git release of cross, but there should hopefully be a new release soon, so it probably makes more sense to wait for that. (Though there's no real timeline for what "soon" means here; it was supposed to release a year ago, but there is still activity at least.) It also only enables the new syscall on GNU/Linux targets, because that's all nix exposes, even though it exists on other OSs and libc implementations. Someone might want to file a PR upstream if they'd like wider support, or we could write our own wrapper around libc.As for the PR itself, it does the classic "ask forgiveness, not permission" TOCTOU solution: if there's any behavior depending on whether there's an existing file at the target, just try to move anyway with the
RENAME_NOREPLACE
flag, and handle theEEXIST
case if it occurs. This restructuring should also remove some extraneous system calls, especially on Windows, where there was a bunch of duplicate work being done.