1
Fork 0
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:
Ludovic Courtès 2020-06-19 20:56:38 +02:00
parent 52baa45d40
commit c7f76d94da
2 changed files with 43 additions and 5 deletions

View file

@ -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

View file

@ -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
;; ;;