From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.user Subject: Re: What is the output port of `system*'? Date: Sun, 27 Apr 2014 02:09:29 -0400 Message-ID: <87lhur8fs6.fsf@yeeloong.lan> References: <87mwf7hnly.fsf@nebulosa.milkyway> <87siozn2e7.fsf@taylan.uni.cx> <87zjj7fifp.fsf@nebulosa.milkyway> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1398580137 19973 80.91.229.3 (27 Apr 2014 06:28:57 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 27 Apr 2014 06:28:57 +0000 (UTC) Cc: guile-user@gnu.org To: "Diogo F. S. Ramos" Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Sun Apr 27 08:28:50 2014 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WeIa0-0003rU-R3 for guile-user@m.gmane.org; Sun, 27 Apr 2014 08:28:48 +0200 Original-Received: from localhost ([::1]:38185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WeIa0-0004VQ-BK for guile-user@m.gmane.org; Sun, 27 Apr 2014 02:28:48 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WeIZm-0004VA-IF for guile-user@gnu.org; Sun, 27 Apr 2014 02:28:40 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WeIZg-0008S8-9S for guile-user@gnu.org; Sun, 27 Apr 2014 02:28:34 -0400 Original-Received: from world.peace.net ([96.39.62.75]:38050) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WeIZg-0008S2-50 for guile-user@gnu.org; Sun, 27 Apr 2014 02:28:28 -0400 Original-Received: from 209-6-91-212.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.91.212] helo=yeeloong.lan) by world.peace.net with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1WeIIq-00069d-8I; Sun, 27 Apr 2014 02:11:04 -0400 In-Reply-To: <87zjj7fifp.fsf@nebulosa.milkyway> (Diogo F. S. Ramos's message of "Sun, 27 Apr 2014 02:30:18 -0300") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 96.39.62.75 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:11232 Archived-At: "Diogo F. S. Ramos" writes: >> "Diogo F. S. Ramos" 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