civodul pushed a commit to branch master in repository shepherd. commit 329cec8b6fcc57f945e748793470f573b2b449a3 Author: Ludovic Courtès <l...@gnu.org> Date: Wed Jul 11 23:12:28 2018 +0200
shepherd: Preserve empty lines in action messages. Previously, "herd hi test-2" in the example added by this commit would lack the empty line between "start" and "end". * modules/shepherd.scm (%not-newline): Remove. (process-command)[get-messages]: Use 'string-split' plus some post-processing instead of 'string-tokenize'. * modules/shepherd/comm.scm (%not-newline): Remove. (make-shepherd-output-port): Use 'string-split' instead of 'string-tokenize'. * tests/basic.sh: Add #:actions in 'test-2' and test the new action. --- modules/shepherd.scm | 18 +++++++++++++----- modules/shepherd/comm.scm | 5 +---- tests/basic.sh | 14 +++++++++++++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/modules/shepherd.scm b/modules/shepherd.scm index 5d97598..1efe4ce 100644 --- a/modules/shepherd.scm +++ b/modules/shepherd.scm @@ -284,9 +284,6 @@ ;; Maybe we got EPIPE while writing to SOCK, or something like that. (false-if-exception (close sock))))) -(define %not-newline - (char-set-complement (char-set #\newline))) - (define (process-command command port) "Interpret COMMAND, a command sent by the user, represented as a <shepherd-command> object. Send the reply to PORT." @@ -302,8 +299,19 @@ (open-output-string))) (define (get-messages) - (string-tokenize (get-output-string message-port) - %not-newline)) + (let* ((str (get-output-string message-port)) + (lst (string-split str #\newline))) + ;; 'string-tokenize' swallows empty lines, which is not great, + ;; and 'string-split' doesn't distinguish between an empty line + ;; and this empty string, which is not great either. So we hack + ;; our way the best we can. + (cond ((string-null? str) + '()) + ;; If STR ends in \n, drop the trailing empty string since + ;; that would lead the client to print an extra newline. + ((string-suffix? "\n" str) + (drop-right lst 1)) + (else lst)))) (parameterize ((%current-client-socket message-port)) (guard (c ((service-error? c) diff --git a/modules/shepherd/comm.scm b/modules/shepherd/comm.scm index cbd8686..43110a7 100644 --- a/modules/shepherd/comm.scm +++ b/modules/shepherd/comm.scm @@ -282,9 +282,6 @@ available." (call-with-syslog-port close-port))) "w")) ;output port -(define %not-newline - (char-set-complement (char-set #\newline))) - ;; We provide our own output mechanism, because we have certain ;; special needs; most importantly, we want to send output to herd ;; sometimes. @@ -312,7 +309,7 @@ available." (if (not (string-index str #\newline)) (set! buffer (cons str buffer)) (let* ((str (string-concatenate-reverse (cons str buffer))) - (lines (string-tokenize str %not-newline))) + (lines (string-split str #\newline))) (define prefix (strftime (%current-logfile-date-format) (localtime (current-time)))) diff --git a/tests/basic.sh b/tests/basic.sh index 2ecd8fb..fc53aa7 100644 --- a/tests/basic.sh +++ b/tests/basic.sh @@ -1,5 +1,5 @@ # GNU Shepherd --- Test basic communication capabilities. -# Copyright © 2013, 2014, 2016, 2017 Ludovic Courtès <l...@gnu.org> +# Copyright © 2013, 2014, 2016, 2017, 2018 Ludovic Courtès <l...@gnu.org> # Copyright © 2016 Mathieu Lirzin <m...@gnu.org> # Copyright © 2014 Alex Sassmannshausen <alex.sassmannshau...@gmail.com> # @@ -54,6 +54,10 @@ cat > "$conf"<<EOF #t) #:stop (lambda _ (delete-file "$stamp-2")) + #:actions (make-actions (hi "Say hi." + (lambda _ + (display "start\n\nend\n") + #t))) #:respawn? #f) (make <service> #:provides '(broken) @@ -94,6 +98,14 @@ then false; else true; fi $herd enable test-2 $herd start test-2 +# Try a custom action; make sure we get all the lines, including the empty +# lines (this was not the case in 0.4.0.) +$herd doc test-2 action hi | grep "Say hi\." +$herd hi test-2 +$herd hi test-2 | grep '^start$' +$herd hi test-2 | grep '^end$' +test `$herd hi test-2 | wc -l` -eq 3 + # This used to crash shepherd: <http://bugs.gnu.org/24684>. if $herd enable test-2 with extra arguments then false; else true; fi