diff options
author | Ludovic Courtès <ludo@gnu.org> | 2019-06-13 13:24:35 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2019-06-13 13:24:35 +0200 |
commit | d9bbfe042e06df35c12e4b8f53bfb1889cba90bf (patch) | |
tree | 9f34077cd824e8955be4ed2b5f1a459aa8076489 /guix/build/syscalls.scm | |
parent | f87a7cc60e058d2e07560d0d602747b567d9dce4 (diff) | |
parent | 47f2168b6fabb105565526b2a1243eeeb13008fe (diff) | |
download | guix-patches-d9bbfe042e06df35c12e4b8f53bfb1889cba90bf.tar guix-patches-d9bbfe042e06df35c12e4b8f53bfb1889cba90bf.tar.gz |
Merge branch 'master' into core-updates
Diffstat (limited to 'guix/build/syscalls.scm')
-rw-r--r-- | guix/build/syscalls.scm | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index 3abe65bc4f..5c2eb3c14d 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -81,7 +81,11 @@ fdatasync pivot-root scandir* + fcntl-flock + lock-file + unlock-file + with-file-lock set-thread-name thread-name @@ -1067,6 +1071,42 @@ exception if it's already taken." ;; Presumably we got EAGAIN or so. (throw 'flock-error err)))))) +(define (lock-file file) + "Wait and acquire an exclusive lock on FILE. Return an open port." + (let ((port (open-file file "w0"))) + (fcntl-flock port 'write-lock) + port)) + +(define (unlock-file port) + "Unlock PORT, a port returned by 'lock-file'." + (fcntl-flock port 'unlock) + (close-port port) + #t) + +(define (call-with-file-lock file thunk) + (let ((port (catch 'system-error + (lambda () + (lock-file file)) + (lambda args + ;; When using the statically-linked Guile in the initrd, + ;; 'fcntl-flock' returns ENOSYS unconditionally. Ignore + ;; that error since we're typically the only process running + ;; at this point. + (if (= ENOSYS (system-error-errno args)) + #f + (apply throw args)))))) + (dynamic-wind + (lambda () + #t) + thunk + (lambda () + (when port + (unlock-file port)))))) + +(define-syntax-rule (with-file-lock file exp ...) + "Wait to acquire a lock on FILE and evaluate EXP in that context." + (call-with-file-lock file (lambda () exp ...))) + ;;; ;;; Miscellaneous, aka. 'prctl'. |