unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: "Diogo F. S. Ramos" <dfsr@riseup.net>
Cc: guile-user@gnu.org
Subject: Re: What is the output port of `system*'?
Date: Sun, 27 Apr 2014 02:09:29 -0400	[thread overview]
Message-ID: <87lhur8fs6.fsf@yeeloong.lan> (raw)
In-Reply-To: <87zjj7fifp.fsf@nebulosa.milkyway> (Diogo F. S. Ramos's message of "Sun, 27 Apr 2014 02:30:18 -0300")

"Diogo F. S. Ramos" <dfsr@riseup.net> writes:

>> "Diogo F. S. Ramos" <dfsr@riseup.net> writes:
>>
>>> The following program doesn't output to a string, which I expected.
>>>
>>> (define foo
>>>   (with-output-to-string
>>>     (lambda ()
>>>       (system* "ls" "/tmp"))))
>>
>> As the manual says about `system*':
>>> The command is executed using fork and execlp.
>>
>> That implies certain restrictions.  See (ice-9 popen), documented in
>> (info "(guile) Pipes").  That also spawns a process but sets its stdout
>> to a Unix pipe for which it gives you a Guile port, from which you can
>> drain the output to construct a string.
>
> Thanks for the pipe reference.
>
> Indeed, something can probably be written with these pipes to achieve
> what my sample program tried to do tho the higher issue remains.
>
>> (Details: `with-output-to-string' could be said to work by setting the
>> current output port to some special value (a "string port" I guess) that
>> tells the deepest Guile IO procedures to construct a string instead of
>> writing to a file descriptor; when you spawn a separate process you
>> obviously lose this ability, the spawned process simply inherits the
>> current stdout file descriptor of the Guile process and writes to that.)
>
> I'm not sure about the underlying implementation, but I expected all
> output to (current-output-port) going to the resulting string, hence my
> question.

All output to (current-output-port) _does_ go into the resulting string.
However, when you launch a subprocess using 'system*', the output of
that process does _not_ go to (current-output-port).  Instead, it goes
to POSIX file descriptor 1, which is left unchanged by the Scheme
constructs that change (current-output-port).  Ditto for
(current-input-port) and (current-error-port).  There are at least two
reasons for this:

* POSIX file descriptors cannot represent all of the types of ports
  supported by Guile, such as string ports and custom binary ports.

* The current-output-port is a fluid variable, which among other things
  is thread-local.  Obviously, POSIX file descriptors are per-process.

> As an example of this behavior, I point to the following Racket program:
>
> #lang racket
>
> (define foo
>   (with-output-to-string
>     (lambda ()
>       (system* (find-executable-path "ls") "/tmp"))))

I agree that it would be nice to make this work as you expected.  In
order to handle ports that are not simply raw POSIX file descriptors
(e.g. string ports), we'd need to create a pipe behind the scenes, and
arrange for thread(s) in the current process to copy data between the
pipe(s) and the Scheme port.

I'd like to do this at some point, although for the sake of backward
compatibility we'd probably have to leave 'system' and 'system*' as-is
and create a new API that works more intuitively.

      Mark



  reply	other threads:[~2014-04-27  6:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-26 19:55 What is the output port of `system*'? Diogo F. S. Ramos
2014-04-26 22:37 ` Taylan Ulrich Bayirli/Kammer
2014-04-27  5:30   ` Diogo F. S. Ramos
2014-04-27  6:09     ` Mark H Weaver [this message]
2014-04-27 19:27       ` Diogo F. S. Ramos

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=87lhur8fs6.fsf@yeeloong.lan \
    --to=mhw@netris.org \
    --cc=dfsr@riseup.net \
    --cc=guile-user@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).