unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Ricardo Wurmus <rekado@elephly.net>
To: Felix Lechner <felix.lechner@lease-up.com>
Cc: 43364@debbugs.gnu.org, pinoaffe@airmail.cc
Subject: bug#43364: with-output-to-port works with file ports
Date: Fri, 08 Sep 2023 21:06:11 +0200	[thread overview]
Message-ID: <877cp05vqp.fsf@elephly.net> (raw)
In-Reply-To: <CAFHYt54Bd1RXJ3rzq8d9_kAHF0FUrAFqbMzNp2zCbCjptGo2EQ@mail.gmail.com>


Felix Lechner via "Bug reports for GUILE, GNU's Ubiquitous Extension Language" <bug-guile@gnu.org> writes:

> Hi,
>
> In an interesting (or perhaps maddening) inconsistency,
> 'with-output-to-port' captures stdout from system* here
>
> (call-with-output-file "/tmp/test.log"
>   (lambda (port)
>     (with-output-to-port
>       port
>       (lambda ()
>         (system* "mktemp" "-d")))))
>
> but 'with-output-to-string' does not do so here
>
> (with-output-to-string
>   (lambda ()
>     (system* "mktemp" "-d")))
>
> According to lloda on #guile, system* handles the redirection only
> when the current ports are file ports. Thanks for that pointer!

That’s correct.  I’ve been using the following monstrosity to capture
and process output.  Perhaps someone finds a prettier way?

--8<---------------cut here---------------start------------->8---
(define* (call-with-output-processor command proc #:optional capture-stderr?)
  "Silently execute COMMAND, a list of strings representing an
executable with its arguments, and apply PROC to every line printed to
standard output and, optionally when CAPTURE-STDERR? is #T, standard
error.  Return the exit status of COMMAND."
  ;; We can only capture a program's standard error by parameterizing
  ;; current-error-port to a *file* port before using system* or
  ;; open-pipe*.  The process will write its standard error stream to
  ;; the provided file descriptor.  Meanwhile we read from the file
  ;; descriptor (blocking) for new lines until the process exits.
  (match (socketpair PF_UNIX SOCK_STREAM 0)
    ((in . out)
     (let ((err (if capture-stderr?
                    (dup out)
                    (%make-void-port "w"))))
       (catch #true
         (lambda ()
           (let ((thread
                  (parameterize ((current-error-port err)
                                 (current-output-port out))
                    (call-with-new-thread
                     (lambda ()
                       (let ((status
                              (status:exit-val
                               (apply system* command))))
                         (close-port err)
                         (close-port out)
                         status))))))
             (let loop ()
               (match (read-line in 'concat)
                 ((? eof-object?)
                  (for-each
                   (lambda (port)
                     (false-if-exception (close-port port)))
                   (list err out in))
                  (join-thread thread))
                 (line
                  (proc line)
                  (loop))))))
         (lambda (key . args)
           (for-each
            (lambda (port)
              (false-if-exception (close-port port)))
            (list err out in))
           (apply throw key args)))))))
--8<---------------cut here---------------end--------------->8---


-- 
Ricardo





  reply	other threads:[~2023-09-08 19:06 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-12 20:59 bug#43364: Possible bug with output redirection pinoaffe
2020-09-13  7:13 ` tomas
2023-09-08 17:53 ` bug#43364: with-output-to-port works with file ports Felix Lechner via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2023-09-08 19:06   ` Ricardo Wurmus [this message]
2024-04-23 16:32 ` Fabio Natali
2024-04-24  7:00   ` Tony Garnock-Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877cp05vqp.fsf@elephly.net \
    --to=rekado@elephly.net \
    --cc=43364@debbugs.gnu.org \
    --cc=felix.lechner@lease-up.com \
    --cc=pinoaffe@airmail.cc \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).