mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
popen: 'open-process' returns unbuffered ports.
* module/ice-9/popen.scm (open-process)[unbuffered, fdes-pair]: New procedures. Use them. Return unbuffered ports. * test-suite/tests/popen.test ("open-pipe*"): New test prefix.
This commit is contained in:
parent
52baa45d40
commit
c7f76d94da
2 changed files with 43 additions and 5 deletions
|
@ -99,13 +99,28 @@ process (based on pipes) is created and returned. @var{mode} specifies
|
||||||
whether an input, an output or an input-output port to the process is
|
whether an input, an output or an input-output port to the process is
|
||||||
created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
|
created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
|
||||||
or @code{OPEN_BOTH}."
|
or @code{OPEN_BOTH}."
|
||||||
|
(define (unbuffered port)
|
||||||
|
(setvbuf port 'none)
|
||||||
|
port)
|
||||||
|
|
||||||
|
(define (fdes-pair ports)
|
||||||
|
(and ports
|
||||||
|
(cons (port->fdes (car ports)) (port->fdes (cdr ports)))))
|
||||||
|
|
||||||
(let* ((from (and (or (string=? mode OPEN_READ)
|
(let* ((from (and (or (string=? mode OPEN_READ)
|
||||||
(string=? mode OPEN_BOTH)) (pipe->fdes)))
|
(string=? mode OPEN_BOTH))
|
||||||
|
(pipe)))
|
||||||
(to (and (or (string=? mode OPEN_WRITE)
|
(to (and (or (string=? mode OPEN_WRITE)
|
||||||
(string=? mode OPEN_BOTH)) (pipe->fdes)))
|
(string=? mode OPEN_BOTH))
|
||||||
(pid (piped-process command args from to)))
|
(pipe)))
|
||||||
(values (and from (fdes->inport (car from)))
|
(pid (piped-process command args
|
||||||
(and to (fdes->outport (cdr to))) pid)))
|
(fdes-pair from)
|
||||||
|
(fdes-pair to))))
|
||||||
|
;; The original 'open-process' procedure would return unbuffered
|
||||||
|
;; ports; do the same here.
|
||||||
|
(values (and from (unbuffered (car from)))
|
||||||
|
(and to (unbuffered (cdr to)))
|
||||||
|
pid)))
|
||||||
|
|
||||||
(define (open-pipe* mode command . args)
|
(define (open-pipe* mode command . args)
|
||||||
"Executes the program @var{command} with optional arguments
|
"Executes the program @var{command} with optional arguments
|
||||||
|
|
|
@ -196,6 +196,29 @@ exec 2>~a; read REPLY"
|
||||||
(close-pipe port)
|
(close-pipe port)
|
||||||
result))))))
|
result))))))
|
||||||
|
|
||||||
|
|
||||||
|
(with-test-prefix "open-pipe*"
|
||||||
|
|
||||||
|
(pass-if-equal "OPEN_BOTH"
|
||||||
|
'(0 (good!))
|
||||||
|
;; This test ensures that the ports that underlie the read/write
|
||||||
|
;; port are unbuffered. If they were buffered, the child process
|
||||||
|
;; would wait in 'read' forever.
|
||||||
|
(let ((pipe (open-pipe* OPEN_BOTH "guile" "-c"
|
||||||
|
(object->string
|
||||||
|
'(begin
|
||||||
|
(setvbuf (current-output-port) 'line)
|
||||||
|
(write '(hello!))
|
||||||
|
(newline)
|
||||||
|
(let ((greeting (read)))
|
||||||
|
(write '(good!))))))))
|
||||||
|
(setvbuf pipe 'line)
|
||||||
|
(let ((return (read pipe)))
|
||||||
|
(write '(hi!) pipe)
|
||||||
|
(newline pipe)
|
||||||
|
(let ((last (read pipe)))
|
||||||
|
(list (close-pipe pipe) last))))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; close-pipe
|
;; close-pipe
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue