Newsgroups: comp.lang.scheme.scsh
Subject: Replicating output
From: Olin Shivers <shivers@lambda.ai.mit.edu>
Date: 09 Mar 2000 18:57:08 -0500
Message-ID: <qijya7rlmsr.fsf@lambda.ai.mit.edu>
Organization: Artificial Intelligence Lab, MIT
From: Friedrich Dominicus <Friedrich.Dominicus@inka.de>
Newsgroups: comp.lang.scheme.scsh
Subject: How to do that
Date: Thu, 09 Mar 2000 08:25:56 +0100
I want to run an external program (e.g echo and redirect it's output to
different locations e.g the current-output-port should be dupped and than
I want to write out the output to echo to different files
Friedrich-
Unfortunately, what you want is pretty tricky in the general case. You
have to answer some questions about resource consumption. Suppose I'm
writing the same data out to two different consumers. What happens if one
of these consumers accepts data, and one doesn't? Does my program block?
That is, do we run at the slowest rate of all consumers? Do we buffer
data for the guy that's behind so the fast consumer can proceed?
If you simply want to block, then life is easy. Remember that scsh lets
you mix Scheme computation into pipelines and other process forms with
the (BEGIN ...) process form. (Pun intended.) So you can write a simple
little 8-liner like this
(define (replicate-stdin . outs)
(let ((buf (make-string 4096)))
(let lp ()
(let ((n (read-string/partial! buf)))
(if (> n 0) ; Not yet at EOF
(begin (for-each (lambda (out) (write-string buf out 0 n))
outs)
(lp)))))))
and use it like this
(| (zcat ,tarball)
(begin (replicate-stdin (current-output-port)
(open-output-file &/tmp/logit;)
some-other-output-port)))
But... remember that if stdout is hooked up to a pipe, and the guy
on the other end stops reading data, then REPLICATE-STDIN will hang
in a write to that pipe eventually, and the /tmp/logit will also starve.
If you want something fancier, you have to work harder.
-Olin
Up |