[plt-scheme] the make-pipe

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Dec 6 08:39:07 EST 2007

At Thu, 6 Dec 2007 18:20:07 +0800, yug at ios.ac.cn wrote:
> (module test-mem mzscheme
>   (require (lib "process.ss"))
>   (define null-port (open-output-file "/dev/null" 'append))
>   (define null-iport (open-input-file "/dev/null"))
>   (define std-oport (current-output-port))
> 
>   (define (x) (let-values ([(r w) (make-pipe)])
>                 (process/ports w null-iport null-port "/sbin/sysctl -a")
>                 (process/ports std-oport r  null-port "grep
> vm.min_free_kbytes")
>               ))
>   (define (y) (process/ports std-oport null-iport null-port "/sbin/sysctl
> -a| grep vm.min_free.kbytes"))
>   (define (z)
>     (let-values ([(r w) (make-pipe)])
>       (process/ports w null-iport null-port "/sbin/sysctl -a")
>       (let loop ()
>         (let ([v (read-line r)])
>           (if (eof-object? r)
>               (void)
>             (begin
>               (fprintf std-oport "~a~n" v)
>               (loop))
>             )))))
>   )
> 
> ------------------------------------
> 
> Welcome to DrScheme, version 371.3-svn7nov2007 [3m].
> Language: (module ...).
> > (x)
> (#f #f 11744 #f #<procedure:control>)
> > (y)
> (#f #f 11745 #f #<procedure:control>)
> vm.min_free_kbytes = 5858
> 
> 1.why (x) and (y) is different?

I'm not sure. On my machine, they work the same when I run in plain
MzScheme, but differently in DrScheme. I'll have to investigate more.

> 2. why (z) could not terminate?

Nothing closes the write side of the pipe.

In both `x' and `z', I think you want to use a returned port from
`process/ports' instead of supplying the write end of a pipe (which
creates extra layer of indirection):

  (define (x) 
    ;; this is what `/sbin/sysctl -a | grep ...' does in the shell:
    (let ([p (process/ports #f null-iport null-port "/sbin/sysctl -a")])
      (process/ports std-oport (car p) null-port "grep vm.min_free_kbytes")
      (close-input-port (car p))))

  (define (z)
    (let* ([p (process/ports #f null-iport null-port "/sbin/sysctl -a")]
           [r (car p)])
      (let loop ()
        (let ([v (read-line r)])
          (if (eof-object? v)
              (void)
              (begin
                (fprintf std-oport "~a~n" v)
                (loop)))))
      (close-input-port r)))

When the process ends, the OS closes the write end of the process's
stdout is closed, so the read end see an EOF.


Matthew



Posted on the users mailing list.