diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2026-08-25 11:31:59 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2026-08-27 14:41:25 +0200 |
| commit | 1a3d801d98f56cf3d915b21d17aa5f29b542ebb9 (patch) | |
| tree | bbbe6c4492a676e7cdf999f7cb27b83ce832ee72 | |
| parent | 9034c3f578b7b9e91aadd3c00ec619cee84411fe (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.scm | 21 |
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 |
| 1586 | to MODE." | 1586 | false and the lock cannot be acquired instantaneously, throw to 'flock-error. |
| 1587 | Return 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." |
