summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/rust-codex-0.98.0-arg0-file-lock.patch
blob: 62298d95725161d96371e795d8c2c5e61257dbc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Author: Danny Milosavljevic <dannym@friendly-machines.com>
Date: 2026-02-07
License: ASL2.0
Subject: Use libc::flock instead of unstable std File::try_lock().

The file_lock feature is tracked at <https://github.com/rust-lang/rust/issues/130994>
and is not yet stable in old Rust versions like Rust 1.88.

diff -ruN a/codex-rs/arg0/Cargo.toml b/codex-rs/arg0/Cargo.toml
--- a/codex-rs/arg0/Cargo.toml
+++ b/codex-rs/arg0/Cargo.toml
@@ -17,5 +17,6 @@
 codex-core = { workspace = true }
 codex-linux-sandbox = { workspace = true }
 dotenvy = { workspace = true }
+libc = { workspace = true }
 tempfile = { workspace = true }
 tokio = { workspace = true, features = ["rt-multi-thread"] }
diff -ruN a/codex-rs/arg0/src/lib.rs b/codex-rs/arg0/src/lib.rs
--- a/codex-rs/arg0/src/lib.rs
+++ b/codex-rs/arg0/src/lib.rs
@@ -5,6 +5,8 @@

 use codex_core::CODEX_APPLY_PATCH_ARG1;
 #[cfg(unix)]
+use std::os::unix::io::AsRawFd;
+#[cfg(unix)]
 use std::os::unix::fs::symlink;
 use tempfile::TempDir;

@@ -13,6 +15,18 @@
 const MISSPELLED_APPLY_PATCH_ARG0: &str = "applypatch";
 const LOCK_FILENAME: &str = ".lock";

+// FIXME: Remove this helper when Rust provides stable file locking API.
+// The file_lock feature is tracked at <https://github.com/rust-lang/rust/issues/130994>.
+#[cfg(unix)]
+fn try_lock_exclusive(file: &File) -> std::io::Result<()> {
+    let ret = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
+    if ret == 0 {
+        Ok(())
+    } else {
+        Err(std::io::Error::last_os_error())
+    }
+}
+
 /// Keeps the per-session PATH entry alive and locked for the process lifetime.
 pub struct Arg0PathEntryGuard {
     _temp_dir: TempDir,
@@ -216,7 +230,7 @@
         .create(true)
         .truncate(false)
         .open(&lock_path)?;
-    lock_file.try_lock()?;
+    try_lock_exclusive(&lock_file)?;

     for filename in &[
         APPLY_PATCH_ARG0,
@@ -307,10 +321,10 @@
         Err(err) => return Err(err),
     };

-    match lock_file.try_lock() {
+    match try_lock_exclusive(&lock_file) {
         Ok(()) => Ok(Some(lock_file)),
-        Err(std::fs::TryLockError::WouldBlock) => Ok(None),
-        Err(err) => Err(err.into()),
+        Err(ref e) if e.raw_os_error() == Some(libc::EWOULDBLOCK) => Ok(None),
+        Err(err) => Err(err),
     }
 }

@@ -318,6 +332,7 @@
 mod tests {
     use super::LOCK_FILENAME;
     use super::janitor_cleanup;
+    use super::try_lock_exclusive;
     use std::fs;
     use std::fs::File;
     use std::path::Path;
@@ -350,7 +365,7 @@
         let dir = root.path().join("locked");
         fs::create_dir(&dir)?;
         let lock_file = create_lock(&dir)?;
-        lock_file.try_lock()?;
+        try_lock_exclusive(&lock_file)?;

         janitor_cleanup(root.path())?;