fix(release): support atomic installation on musl Linux

This commit is contained in:
elky
2026-09-07 01:07:34 +08:00
parent 1b01b08c31
commit 6948852992
@@ -1399,7 +1399,8 @@ fn rename_release_dir_noreplace(source: &Path, destination: &Path) -> Result<(),
#[cfg(target_os = "linux")]
// SAFETY: both paths are valid NUL-terminated strings and remain alive for the call.
let status = unsafe {
libc::renameat2(
libc::syscall(
libc::SYS_renameat2,
libc::AT_FDCWD,
source.as_ptr(),
libc::AT_FDCWD,
@@ -2625,6 +2626,27 @@ mod tests {
std::fs::remove_dir_all(dir).ok();
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
#[test]
fn update_preserves_existing_empty_release_destination() {
let dir = temp_test_dir("existing-empty-release");
let source = dir.join("prepared-v1.2.3");
let release = dir.join("releases/v1.2.3");
std::fs::create_dir_all(&source).expect("prepared release should be created");
std::fs::create_dir_all(&release).expect("existing release should be created");
let err = rename_release_dir_noreplace(&source, &release)
.expect_err("existing empty release must not be replaceable");
assert!(err.contains("拒绝覆盖"));
assert!(
release.is_dir(),
"failed install must retain its destination"
);
assert!(source.is_dir(), "failed install must retain its source");
std::fs::remove_dir_all(dir).ok();
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
#[test]
fn update_atomically_installs_absent_release_destination() {