guix_mirror_bot pushed a commit to branch master
in repository guix.
commit 1a3d801d98f56cf3d915b21d17aa5f29b542ebb9
Author: Ludovic Courtès <[email protected]>
AuthorDate: Tue Aug 25 11:31:59 2026 +0200
syscalls: Fix file descriptor leak in ‘lock-file’.
Until now, calls to ‘lock-file’ with #:wait? #f throwing to 'flock-error
would
leak ‘port’. The underlying file descriptor would be closed once ‘port’ is
GC’d. This change ensures the file descriptor is closed right away.
* guix/build/syscalls.scm (lock-file): Catch 'flock-error around
‘fcntl-flock’
call. Close port upon exception. Clarify docstring.
Signed-off-by: Ludovic Courtès <[email protected]>
---
guix/build/syscalls.scm | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index e92bca7aaa..da3f56350f 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014-2025 Ludovic Courtès <[email protected]>
+;;; Copyright © 2014-2026 Ludovic Courtès <[email protected]>
;;; Copyright © 2015 David Thompson <[email protected]>
;;; Copyright © 2015 Mark H Weaver <[email protected]>
;;; Copyright © 2017 Mathieu Othacehe <[email protected]>
@@ -1582,13 +1582,20 @@ exception if it's already taken."
(define* (lock-file file #:optional (mode "w0")
#:key (wait? #t))
- "Wait and acquire an exclusive lock on FILE. Return an open port according
-to MODE."
+ "Acquire an exclusive lock on FILE, waiting if WAIT? is true; when WAIT? is
+false and the lock cannot be acquired instantaneously, throw to 'flock-error.
+Return an open port according to MODE."
(let ((port (open-file file mode)))
- (fcntl-flock port
- (if (output-port? port) 'write-lock 'read-lock)
- #:wait? wait?)
- port))
+ (catch 'flock-error
+ (lambda ()
+ (fcntl-flock port
+ (if (output-port? port) 'write-lock 'read-lock)
+ #:wait? wait?)
+ port)
+ (lambda (key . args)
+ ;; This is typically EAGAIN if WAIT? is false.
+ (close-port port)
+ (apply throw key args)))))
(define (unlock-file port)
"Unlock PORT, a port returned by 'lock-file', and close it."