civodul pushed a commit to branch main
in repository shepherd.

commit 8d88024e0898dd7d4581c4e977c9786af734a855
Author: Ludovic Courtès <l...@gnu.org>
AuthorDate: Sat Apr 12 17:34:21 2025 +0200

    shepherd: ‘system*’ and ‘system’ replacements honor current directory.
    
    Fixes <https://issues.guix.gnu.org/77707>.
    
    * modules/shepherd.scm (main): Pass #:directory to ‘spawn-command’ for
    ‘system*’ replacement.
    * modules/shepherd/service.scm (spawn-shell-command): Likewise.
    * tests/system-star.sh: Test it.
    * NEWS: Update.
    
    Reported-by: Maxim Cournoyer <maxim.courno...@gmail.com>
---
 NEWS                         |  6 ++++++
 modules/shepherd.scm         |  2 +-
 modules/shepherd/service.scm |  3 ++-
 tests/system-star.sh         | 17 ++++++++++++++++-
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 3a212a0..f843b62 100644
--- a/NEWS
+++ b/NEWS
@@ -79,6 +79,12 @@ non-blocking (O_NONBLOCK) to the process it spawns, except 
when using
 This bug would manifest on GNU/Hurd where accept(2) in this child process
 would return EAGAIN, which some daemons did not correctly handle.
 
+** ‘system*’ and ‘system’ replacements honor current directory
+   (<https://issues.guix.gnu.org/77707>)
+
+The ‘system*’ and ‘system’ replacements in the ‘shepherd’ process now run the
+given command in the current directory rather than under
+(default-service-directory).
 
 * Changes in 1.0.3
 
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index a35a415..68e402b 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -584,7 +584,7 @@ fork in the child process."
                            ;; and thus a continuation barrier.  Replace it.
                            (put-char port #\newline)))
                 (system* (lambda command
-                           (spawn-command command)))
+                           (spawn-command command #:directory (getcwd))))
                 (system spawn-shell-command)
                 (primitive-load primitive-load*)
                 (call-with-input-file call-with-input-file/close-on-exec)
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index 654506d..4cecf68 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -1891,7 +1891,8 @@ process is still running after @var{grace-period} 
seconds, send it
 This is similar to Guile's @code{system} procedure but does not block while
 waiting for the shell to terminate."
   (spawn-command (list (or (getenv "SHELL") "/bin/sh")
-                       "-c" command)))
+                       "-c" command)
+                 #:directory (getcwd)))
 
 ;; Produce a constructor that executes a command.
 (define (make-system-constructor . command)
diff --git a/tests/system-star.sh b/tests/system-star.sh
index fc3cda7..4edcba2 100755
--- a/tests/system-star.sh
+++ b/tests/system-star.sh
@@ -1,5 +1,5 @@
 # GNU Shepherd --- Test whether 'system*' is blocking.
-# Copyright © 2022-2023 Ludovic Courtès <l...@gnu.org>
+# Copyright © 2022-2023, 2025 Ludovic Courtès <l...@gnu.org>
 #
 # This file is part of the GNU Shepherd.
 #
@@ -33,6 +33,8 @@ trap "cat $log || true; rm -f $socket $conf $stamp $log;
 script="while [ ! -f $PWD/$stamp ] ; do sleep 0.1 ; done ; exit \$(cat 
$PWD/$stamp)"
 
 cat > "$conf" <<EOF
+(use-modules ((shepherd support) #:select (with-directory-excursion)))
+
 (register-services
  (list (service
         '(test)
@@ -54,6 +56,12 @@ cat > "$conf" <<EOF
                   (zero? (system* "this command does not exist")))
         #:stop  (const #f)
         #:respawn? #f)
+       (service
+        '(test-current-directory)
+        #:start (lambda _
+                  (with-directory-excursion "${TMPDIR:-/tmp}"
+                     (zero? (system "echo CWD: \$PWD"))))
+        #:respawn? #f)
        (service
         '(test-with-respawn)
         #:start (make-forkexec-constructor
@@ -122,6 +130,13 @@ $herd start test-command-not-found && false
 $herd status test-command-not-found
 $herd status test-command-not-found | grep "stopped"
 
+# Check that 'system*' and 'system' run commands from the current working
+# directory rather than from (default-service-directory).
+$herd start test-current-directory
+$herd status test-current-directory | grep running
+grep "CWD: ${TMPDIR:-/tmp}" "$log"
+$herd stop test-current-directory
+
 # What about a service with a custom 'stop' procedure that uses 'system*'?
 # Stopping the service should not trigger the respawn machinery.
 $herd start test-with-respawn

Reply via email to