guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

07/07: home: services: Fix race condition when detecting first login.


From: guix-commits
Subject: 07/07: home: services: Fix race condition when detecting first login.
Date: Thu, 19 Oct 2023 18:36:04 -0400 (EDT)

civodul pushed a commit to branch master
in repository guix.

commit 6b0a32196982a0a2f4dbb59d35e55833a5545ac6
Author: Carlo Zancanaro <carlo@zancanaro.id.au>
AuthorDate: Wed Oct 11 22:57:19 2023 +1100

    home: services: Fix race condition when detecting first login.
    
    * 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 <ludo@gnu.org>
---
 gnu/home/services.scm | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

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 <andrew@trop.in>
 ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
 ;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
 ;;;
 ;;; 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]