summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2026-08-25 11:31:59 +0200
committerLudovic Courtès <ludo@gnu.org>2026-08-27 14:41:25 +0200
commit1a3d801d98f56cf3d915b21d17aa5f29b542ebb9 (patch)
treebbbe6c4492a676e7cdf999f7cb27b83ce832ee72
parent9034c3f578b7b9e91aadd3c00ec619cee84411fe (diff)
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 <ludo@gnu.org>
-rw-r--r--guix/build/syscalls.scm21
1 files changed, 14 insertions, 7 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index e92bca7aaa3..da3f56350f2 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014-2025 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2014-2026 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2015 David Thompson <davet@gnu.org> 3;;; Copyright © 2015 David Thompson <davet@gnu.org>
4;;; Copyright © 2015 Mark H Weaver <mhw@netris.org> 4;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
5;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> 5;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
@@ -1582,13 +1582,20 @@ exception if it's already taken."
1582 1582
1583(define* (lock-file file #:optional (mode "w0") 1583(define* (lock-file file #:optional (mode "w0")
1584 #:key (wait? #t)) 1584 #:key (wait? #t))
1585 "Wait and acquire an exclusive lock on FILE. Return an open port according 1585 "Acquire an exclusive lock on FILE, waiting if WAIT? is true; when WAIT? is
1586to MODE." 1586false and the lock cannot be acquired instantaneously, throw to 'flock-error.
1587Return an open port according to MODE."
1587 (let ((port (open-file file mode))) 1588 (let ((port (open-file file mode)))
1588 (fcntl-flock port 1589 (catch 'flock-error
1589 (if (output-port? port) 'write-lock 'read-lock) 1590 (lambda ()
1590 #:wait? wait?) 1591 (fcntl-flock port
1591 port)) 1592 (if (output-port? port) 'write-lock 'read-lock)
1593 #:wait? wait?)
1594 port)
1595 (lambda (key . args)
1596 ;; This is typically EAGAIN if WAIT? is false.
1597 (close-port port)
1598 (apply throw key args)))))
1592 1599
1593(define (unlock-file port) 1600(define (unlock-file port)
1594 "Unlock PORT, a port returned by 'lock-file', and close it." 1601 "Unlock PORT, a port returned by 'lock-file', and close it."