unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Jeff Mickey <j@codemac.net>
To: 24680@debbugs.gnu.org
Subject: bug#24680: Documentation / Behavior of open-pipe* with stderr
Date: Wed, 12 Oct 2016 16:18:13 -0700	[thread overview]
Message-ID: <87fuo12m2y.fsf@purestorage.com> (raw)

Hi!

So, I like to build up programs by tieing together a few different
programs, and then replacing parts where I reimplement features in
simpler ways.

Currently, I have a piece of guile code that calls out to dd, and I
wanted to capture the stderr and print it if dd failed to run
successfully. If it ran successfully, I just wanted to swallow it.

I read the following from the guile Info page 7.2.10 Pipes under the
procedure documentation for open-pipe*:

  For an input pipe, the child’s standard output is the pipe and
  standard input is inherited from ‘current-input-port’.  For an
  output pipe, the child’s standard input is the pipe and standard
  output is inherited from ‘current-output-port’.  In all cases cases
  the child’s standard error is inherited from ‘current-error-port’
  (*note Default Ports::).

So, in my assumption, I should be able to use parameterize on
current-error-port, and set it to a string port. Here is some test code:

  (use-modules (ice-9 popen))
  
  (define (port-copy dst src)
    (let ((c (read-char src)))
      (if (eof-object? c)
        dst
        (begin (write-char c dst)
               (port-copy dst src)))))
  
  (define (print-outs one two)
    (format #t "what was stored in stdout:~%~a~%<eond of os>~%" (get-output-string os))
    (format #t "what was stored in stderr:~%~a~%<eond of es>~%" (get-output-string es)))
  
  (let ((os (open-output-string))
        (es (open-output-string)))
    (parameterize ((current-error-port es))
      (let ((rp (open-pipe* OPEN_BOTH "logger" "-s" "help me i'm stderr")))
        (port-copy os rp)
        (status:exit-val (close-pipe rp))))
    (print-outs os es))
  
  (let ((os (open-output-string))
        (es (open-output-string)))
    (parameterize ((current-error-port es))
      (let ((rp (open-pipe* OPEN_BOTH "echo" "help me i'm stdout")))
        (port-copy os rp)
        (status:exit-val (close-pipe rp))))
    (print-outs os es))

This, notably, is unable to print stderr. I tried changing the
parameterize to a call to set-current-error-port, but this didn't work
either, same results where it's blank.

So, clearly, something is wrong.

Then I looked at the source of posix.c & strports.c & fports.h, and it
looks like string ports cannot be used for open-pipe*. 6.14.8 Default
Ports for Input, Output and Errors do not call this out.

I haven't figured out how to fix it yet, but I think it'd be great if
string/byte ports could be used everywhere, including for
stdout/stdin. Seems like we could check if the in/out/error ports are
fd's or not like currently (line 1388 of posix.c) but in the else
case set up some type of thread (or forked process) that goes off and
copies whatever comes out of the fd into a byte or string port.

I don't know enough about the guile C implementation to make more
concrete suggestions.

Thanks in advance. At the least, I feel like the documentation for
open-pipe* and the Default Ports could be improved significantly.

  //  codemac





                 reply	other threads:[~2016-10-12 23:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=87fuo12m2y.fsf@purestorage.com \
    --to=j@codemac.net \
    --cc=24680@debbugs.gnu.org \
    /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).