61 lines
1.7 KiB
Scheme
61 lines
1.7 KiB
Scheme
;;; -*-Scheme-*-
|
|
;;;
|
|
;;; Demonstrate pipes, fork, exec.
|
|
;;;
|
|
;;; (calc-open) -- Open two pipes to/from UNIX dc command
|
|
;;; (calc expr) -- Send expression to dc, return result as a string
|
|
;;; (calc-close) -- Close pipes, wait for child process
|
|
;;;
|
|
;;;
|
|
;;; This program requires vanilla UNIX dc. It does not work with GNU dc,
|
|
;;; because GNU dc uses buffered output even if standard output points to
|
|
;;; a pipe. This means that GNU dc does not produce any output until the
|
|
;;; pipe is closed; the call to read-string therefore just hangs.
|
|
|
|
|
|
(require 'unix)
|
|
|
|
(define calc-from-dc) ; input port: standard output of dc command
|
|
(define calc-to-dc) ; output port: standard input of dc command
|
|
(define calc-dc-pid) ; process-ID of child process running dc
|
|
|
|
(define calc-dc-command "/usr/bin/dc")
|
|
|
|
(define (calc-open)
|
|
(let* ((from (unix-pipe))
|
|
(to (unix-pipe))
|
|
(redirect-fd (lambda (a b)
|
|
(unix-dup a b) (unix-close a))))
|
|
(set! calc-dc-pid (unix-fork))
|
|
(if (zero? calc-dc-pid)
|
|
(begin
|
|
(unix-close (car from))
|
|
(unix-close (cdr to))
|
|
(redirect-fd (car to) 0)
|
|
(redirect-fd (cdr from) 1)
|
|
(unix-exec calc-dc-command '("dc")))
|
|
(begin
|
|
(unix-close (cdr from))
|
|
(unix-close (car to))
|
|
(set! calc-to-dc (unix-filedescriptor->port (cdr to) "w"))
|
|
(set! calc-from-dc (unix-filedescriptor->port (car from) "r"))))))
|
|
|
|
(define (calc expr)
|
|
(format calc-to-dc "~a~%" expr)
|
|
(flush-output-port calc-to-dc)
|
|
(read-string calc-from-dc))
|
|
|
|
(define (calc-close)
|
|
(close-output-port calc-to-dc)
|
|
(close-input-port calc-from-dc)
|
|
(if (feature? 'unix:wait-process)
|
|
(unix-wait-process calc-dc-pid)
|
|
(unix-wait)))
|
|
|
|
|
|
;;; Test -- print sqrt(2):
|
|
|
|
(calc-open)
|
|
(display (calc "10k 2v p")) (newline)
|
|
(calc-close)
|