So you have a Gambit process A that you want to launch Unix processes B and C, such that A outputs to B, which outputs to C, which outputs back to A?<div><br></div><div>Probably you can just rely on Unix' piping primitives for that, something akin to open-process `(app: "/bin/sh" args: ("B" "|" "C"  or "B | C") ..redirection.. #t ?<br>

<br><div class="gmail_quote">2013/1/28 Jussi Piitulainen <span dir="ltr"><<a href="mailto:jpiitula@ling.helsinki.fi" target="_blank">jpiitula@ling.helsinki.fi</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Assuming my previous question came through, I asked about implementing<br>
pipelines of processes in Gambit-C. The problem was that I could not<br>
seem to make the output of one process to connect to the input of the<br>
next on their own.<br>
<br>
I'm now experimenting with Gambit-C threads to bridge those gaps.<br>
Here is a rudimentary implementation of what I want. The comments<br>
indicate things that I think I know I still need to do. I haven't used<br>
threads much before, and never in Scheme.<br>
<br>
The original question stands: am I overlooking some obvious way to do<br>
such pipelines that Gambit-C already has? Because this is the easy 80%<br>
of the work and another 80% sheer tedium probably remains :)<br>
<br>
(define (echo from to) ;should use a buffer<br>
  (do ((line (read-line from) (read-line from)))<br>
      ((eof-object? line))<br>
    (display line to)<br>
    (newline to)))<br>
<br>
(define (piece from to)<br>
  (lambda ()<br>
    (echo from to) ;should allocate a private buffer for echo<br>
    (close-output-port to)  ;stopped using it as output port<br>
    (process-status from))) ;wait for it - maybe time it out?<br>
<br>
(define (end from) ;not closing current output port<br>
  (lambda ()<br>
    (echo from (current-output-port))<br>
    (process-status from)))<br>
<br>
;actually, the end should be controlled by the called altogether! or<br>
;is it now?<br>
<br>
;caller needs to close the first pipe segment as output port, and do I<br>
;need to force some output or close input ports? and errors should be<br>
;handled, including diagnostic output from the processes and failed<br>
;status of any, and not leave processes around on any sort of error if<br>
;possible. oh and do all those threads terminate nicely and always?<br>
<br>
(define (pipe first . rest)<br>
  (let ((first (open-process first)))<br>
    (do ((last first (car rest))<br>
         (rest (map open-process rest) (cdr rest)))<br>
        ((null? rest)<br>
         (thread-start! (make-thread (end last)))<br>
         ;;^altogether mistaken - leave it to the caller<br>
         (values first last))<br>
      (thread-start! (make-thread (piece last (car rest)))))))<br>
<br>
(define (test) ;has hardwired end to echo the output in current output<br>
  (call-with-values ;^fix it so the called handles reading and waiting<br>
      (lambda ()<br>
        (pipe "date" '(path: "tr" arguments: ("0-9" "D"))))<br>
    (lambda (first last)<br>
      (close-output-port first))))<br>
<br>
_______________________________________________<br>
Gambit-list mailing list<br>
<a href="mailto:Gambit-list@iro.umontreal.ca">Gambit-list@iro.umontreal.ca</a><br>
<a href="https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list" target="_blank">https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list</a><br>
</blockquote></div><br></div>