summaryrefslogtreecommitdiff
path: root/gnu/installer/utils.scm
diff options
context:
space:
mode:
authorJosselin Poiret <dev@jpoiret.xyz>2022-01-15 14:50:00 +0100
committerMathieu Othacehe <othacehe@gnu.org>2022-02-02 16:46:43 +0100
commit0b9fbbb4dd24f227c9a708561ba291f6169ad2e6 (patch)
tree3cb7d304cf0653e8d7fbb72f4aa68ec65ab2e04f /gnu/installer/utils.scm
parentc57ec6ed1ee5f2367833c3e11ae7074f114dbf02 (diff)
installer: Capture external commands output.
* gnu/installer/utils.scm (run-external-command-with-handler, run-external-command-with-line-hooks): New variables. (run-command): Use run-external-command-with-line-hooks. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org>
Diffstat (limited to 'gnu/installer/utils.scm')
-rw-r--r--gnu/installer/utils.scm98
1 files changed, 78 insertions, 20 deletions
diff --git a/gnu/installer/utils.scm b/gnu/installer/utils.scm
index 1bff1e12290..66c41ac2a1a 100644
--- a/gnu/installer/utils.scm
+++ b/gnu/installer/utils.scm
@@ -25,7 +25,9 @@
25 #:use-module (srfi srfi-1) 25 #:use-module (srfi srfi-1)
26 #:use-module (srfi srfi-19) 26 #:use-module (srfi srfi-19)
27 #:use-module (srfi srfi-34) 27 #:use-module (srfi srfi-34)
28 #:use-module (ice-9 control)
28 #:use-module (ice-9 match) 29 #:use-module (ice-9 match)
30 #:use-module (ice-9 popen)
29 #:use-module (ice-9 rdelim) 31 #:use-module (ice-9 rdelim)
30 #:use-module (ice-9 regex) 32 #:use-module (ice-9 regex)
31 #:use-module (ice-9 format) 33 #:use-module (ice-9 format)
@@ -34,6 +36,8 @@
34 read-all 36 read-all
35 nearest-exact-integer 37 nearest-exact-integer
36 read-percentage 38 read-percentage
39 run-external-command-with-handler
40 run-external-command-with-line-hooks
37 run-command 41 run-command
38 42
39 syslog-port 43 syslog-port
@@ -78,37 +82,91 @@ number. If no percentage is found, return #f"
78 (and result 82 (and result
79 (string->number (match:substring result 1))))) 83 (string->number (match:substring result 1)))))
80 84
85(define* (run-external-command-with-handler handler command)
86 "Run command specified by the list COMMAND in a child with output handler
87HANDLER. HANDLER is a procedure taking an input port, to which the command
88will write its standard output and error. Returns the integer status value of
89the child process as returned by waitpid."
90 (match-let (((input . output) (pipe)))
91 ;; Hack to work around Guile bug 52835
92 (define dup-output (duplicate-port output "w"))
93 ;; Void pipe, but holds the pid for close-pipe.
94 (define dummy-pipe
95 (with-input-from-file "/dev/null"
96 (lambda ()
97 (with-output-to-port output
98 (lambda ()
99 (with-error-to-port dup-output
100 (lambda ()
101 (apply open-pipe* (cons "" command)))))))))
102 (close-port output)
103 (close-port dup-output)
104 (handler input)
105 (close-port input)
106 (close-pipe dummy-pipe)))
107
108(define (run-external-command-with-line-hooks line-hooks command)
109 "Run command specified by the list COMMAND in a child, processing each
110output line with the procedures in LINE-HOOKS. Returns the integer status
111value of the child process as returned by waitpid."
112 (define (handler input)
113 (and
114 (and=> (get-line input)
115 (lambda (line)
116 (if (eof-object? line)
117 #f
118 (begin (for-each (lambda (f) (f line))
119 (append line-hooks
120 %default-installer-line-hooks))
121 #t))))
122 (handler input)))
123 (run-external-command-with-handler handler command))
124
81(define* (run-command command) 125(define* (run-command command)
82 "Run COMMAND, a list of strings. Return true if COMMAND exited 126 "Run COMMAND, a list of strings. Return true if COMMAND exited
83successfully, #f otherwise." 127successfully, #f otherwise."
84 (define env (environ))
85
86 (define (pause) 128 (define (pause)
87 (format #t (G_ "Press Enter to continue.~%")) 129 (format #t (G_ "Press Enter to continue.~%"))
88 (send-to-clients '(pause)) 130 (send-to-clients '(pause))
89 (environ env) ;restore environment variables
90 (match (select (cons (current-input-port) (current-clients)) 131 (match (select (cons (current-input-port) (current-clients))
91 '() '()) 132 '() '())
92 (((port _ ...) _ _) 133 (((port _ ...) _ _)
93 (read-line port)))) 134 (read-line port))))
94 135
95 (setenv "PATH" "/run/current-system/profile/bin") 136 (installer-log-line "running command ~s" command)
96 137 (define result (run-external-command-with-line-hooks
97 (guard (c ((invoke-error? c) 138 (list %display-line-hook)
98 (newline) 139 command))
99 (format (current-error-port) 140 (define exit-val (status:exit-val result))
100 (G_ "Command failed with exit code ~a.~%") 141 (define term-sig (status:term-sig result))
101 (invoke-error-exit-status c)) 142 (define stop-sig (status:stop-sig result))
102 (installer-log-line "command ~s failed with exit code ~a" 143 (define succeeded?
103 command (invoke-error-exit-status c)) 144 (cond
104 (pause) 145 ((and exit-val (not (zero? exit-val)))
105 #f)) 146 (installer-log-line "command ~s exited with value ~a"
106 (installer-log-line "running command ~s" command) 147 command exit-val)
107 (apply invoke command) 148 (format #t (G_ "Command ~s exited with value ~a")
108 (installer-log-line "command ~s succeeded" command) 149 command exit-val)
109 (newline) 150 #f)
110 (pause) 151 (term-sig
111 #t)) 152 (installer-log-line "command ~s killed by signal ~a"
153 command term-sig)
154 (format #t (G_ "Command ~s killed by signal ~a")
155 command term-sig)
156 #f)
157 (stop-sig
158 (installer-log-line "command ~s stopped by signal ~a"
159 command stop-sig)
160 (format #t (G_ "Command ~s stopped by signal ~a")
161 command stop-sig)
162 #f)
163 (else
164 (installer-log-line "command ~s succeeded" command)
165 (format #t (G_ "Command ~s succeeded") command)
166 #t)))
167 (newline)
168 (pause)
169 succeeded?)
112 170
113 171
114;;; 172;;;