From 8617964d4dbf03d752fbf094600ef977a36a83ec Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Thu, 22 May 2025 14:09:16 +0200 Subject: [PATCH] Fix uvar file mtime force-update (Rust port regression) When two fish processes rewrite the uvar file concurrent, they rely on the uvar file's mtime (queried after taking a lock, if locking is supported) to tell us whether their view of the uvar file is still up-to-date. If it is, they proceed to move it into place atomically via rename(). Since the observable mtime only updates on every OS clock tick, we call futimens() manually to force-update that, to make sure that -- unless both fish conincide on the same *nanosecond* -- other fish will notice that the file changed. Unfortunately, commit 77aeb6a2a88 (Port execution, 2023-10-08) accidentally made us call futimens() only if clock_gettime() failed, instead of when it succeeded. This means that we need to wait for the next clock tick to observe a change in mtime. Any resulting false negatives might have caused us to drop universal variable updates. Reported in https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2098948362 See #10300 --- src/env_universal_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env_universal_common.rs b/src/env_universal_common.rs index 338fe9fd0..b241591d6 100644 --- a/src/env_universal_common.rs +++ b/src/env_universal_common.rs @@ -801,7 +801,7 @@ fn save(&mut self, directory: &wstr) -> bool { { let mut times: [libc::timespec; 2] = unsafe { std::mem::zeroed() }; times[0].tv_nsec = libc::UTIME_OMIT; // don't change ctime - if unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, &mut times[1]) } != 0 { + if unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, &mut times[1]) } == 0 { unsafe { libc::futimens(private_file.as_raw_fd(), ×[0]); }