From 6b0a32196982a0a2f4dbb59d35e55833a5545ac6 Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Wed, 11 Oct 2023 22:57:19 +1100 Subject: home: services: Fix race condition when detecting first login. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/home/services.scm (compute-on-first-login-script): Use open-fdes to atomically check whether a file exists and create it if not. Co-authored-by: Ludovic Courtès --- gnu/home/services.scm | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'gnu/home') diff --git a/gnu/home/services.scm b/gnu/home/services.scm index 8d53f2f4d3..651c068f79 100644 --- a/gnu/home/services.scm +++ b/gnu/home/services.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2021-2023 Andrew Tropin ;;; Copyright © 2021 Xinglu Chen ;;; Copyright © 2022-2023 Ludovic Courtès +;;; Copyright © 2023 Carlo Zancanaro ;;; ;;; This file is part of GNU Guix. ;;; @@ -412,20 +413,29 @@ activation."))) #~(begin (use-modules (guix i18n) (guix diagnostics)) + + (define (claim-first-run file) + (catch #t + (lambda () + ;; This incantation raises an error if FILE already exists, and + ;; creates it otherwise. + (close-fdes + (open-fdes file (logior O_CREAT O_EXCL O_CLOEXEC))) + #t) + (const #f))) + #$%initialize-gettext (let* ((xdg-runtime-dir (or (getenv "XDG_RUNTIME_DIR") (format #f "/run/user/~a" (getuid)))) (flag-file-path (string-append - xdg-runtime-dir "/on-first-login-executed")) - (touch (lambda (file-name) - (call-with-output-file file-name (const #t))))) + xdg-runtime-dir "/on-first-login-executed"))) ;; XDG_RUNTIME_DIR dissapears on logout, that means such trick ;; allows to launch on-first-login script on first login only ;; after complete logout/reboot. (if (file-exists? xdg-runtime-dir) - (unless (file-exists? flag-file-path) - (begin #$@gexps (touch flag-file-path))) + (when (claim-first-run flag-file-path) + #$@gexps) ;; TRANSLATORS: 'on-first-login' is the name of a service and ;; shouldn't be translated (warning (G_ "XDG_RUNTIME_DIR doesn't exists, on-first-login script -- cgit v1.2.3