[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mkfifo


I don't know, if my solution to the problem ist the most elegant one, but
anyway - it works (at least for me ;):

(defun RUN-PROGRAM (prog &key
                         (if-output-exists :overwrite)
                         (wait             t))
  (let* ((outf  (cond ((stringp output) output)
                      ((pathnamep output) (namestring output))
                      ((eq :stream  output)
                       (do ((pn (symbol-name (gensym "/tmp/clrpO"))
                                (symbol-name (gensym "/tmp/clrpO"))))
                           ((null (probe-file pn))
                            (unless (zerop (shell (format NIL "~A ~A"
                                                          *mkfifo-prog* pn)))
                              (error "Can't create fifo - sorry!"))
                      (T NIL)))
         (inf   (cond ((or (stringp input) (pathnamep input)) input)
                      ((eq :stream  input)
                       (do ((pn (symbol-name (gensym "/tmp/clrpI"))
                                (symbol-name (gensym "/tmp/clrpI"))))
                           ((null (probe-file pn))
                            (unless (zerop (shell (format NIL "~A ~A"
                                                          *mkfifo-prog* pn)))
                              (error "Can't create fifo - sorry!"))
                            (open pn
                                  :direction :output
                                  :if-exists :overwrite))))
                      (T NIL)))
         (cmd   (format NIL "~A~{ ~A~}~@[ < ~A~]~@[ ~A~] 2>&1 ~@[ &~]"
                        prog arguments (and inf (namestring inf))
                        (and outf
                              NIL "~A ~A"
                              (case if-output-exists
                                (:append ">> ")
                                (:overwrite "> ")
                                 (when (probe-file outf)
                                   (error "Outfile ~A exists!" outf))
                                 "> ")
                                  "Strange if-output-exists spec ~A"
                        (or (not wait)
                            (eq :stream input)
                            (eq :stream output))))
         (res  (shell (format NIL "exec /bin/sh -c ~S" cmd))))
    (cond ((and (eq :stream input) (eq :stream output))
           (let ((outs (open outf :direction :input)))
             (values (make-two-way-stream outs inf) outs inf)))
          ((eq :stream input)
          ((eq :stream output)
           (open outf :direction :input))
          (T res))))

(defun START-WISH (&key (wish *wish-prog*) (arguments NIL))
  (multiple-value-setq (*wish* *wish-i-stream* *wish-o-stream*)
    (run-program wish
                 :arguments arguments
                 :input     :stream
                 :output    :stream
                 :wait      NIL)))

START-WISH returns a two way stream, that may be used to read from and write to
the wish process. However, you should never try to use "read" or "read-line"
on this stream, but use your own reader, that is implemented in terms of
read-char-no-hang and/or listen. Also remember to use "flush output" on the 
wish-side, after every output-operation, or you will not see anything on the
lisp-stream (until the io-buffer gets filled).

Have fun


Matthias Lindner
FG Intellektik, FB Informatik
Technische Hochschule Darmstadt
Alexanderstr.10, D-64283 Darmstadt
TEL: +49 6151 166651
FAX: +49 6151 165326
NET: matthias@intellektik.informatik.th-darmstadt.de