Skip to content

mv: use RENAME_NOREPLACE when we can #7832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jtracey
Copy link
Contributor

@jtracey jtracey commented Apr 24, 2025

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 the EEXIST 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.

Copy link

GNU testsuite comparison:

GNU test failed: tests/mv/part-rename. tests/mv/part-rename is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/mv/part-symlink. tests/mv/part-symlink is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/misc/stdbuf (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/misc/usage_vs_getopt (passes in this run but fails in the 'main' branch)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mv: -n (--no-clobber) is racy, unlike GNU mv
1 participant