Commit 6510db1e authored by Robert P. Goldman's avatar Robert P. Goldman

Fixes for UIOP:RUN-PROGRAM on ACL.

On ACL, the :INPUT and :OUTPUT arguments to EXCL:RUN-SHELL-COMMAND take
NIL for the behavior of inheriting input and output handles from the
Lisp process.  These were encoded as T in UIOP:RUN-PROGRAM, instead of
NIL, causing ACL to get errors trying to open T as a file designator.

Added a couple of test cases to test-run-program.script to illustrate
the problem.

Note that this fix does not provide the prescribed behavior for :OUTPUT
NIL (which should take the program's output and throw it on the floor).
There is a TODO in uiop:run-program explaining what's missing.  In
brief, ACL's EXCL:RUN-SHELL-COMMAND does not support this behavior out
of the box, so one would have to capture the program's output, and then
throw it on the floor.
parent 98a32bf0
......@@ -34,6 +34,12 @@
(assert-equal "ok 1" (run-program '("echo" "ok 1") :output :line))
(assert-equal '(:ok 1) (run-program '("echo" ":ok 1") :output :forms))
(assert-equal (format nil "ok 1~%") (run-program '("echo" "ok 1") :output :string))
;; this test checks for a problem there was in allegro -- :output :interactive
;; would try to open T as a stream for INPUT.
(assert-equal 0 (run-program "true" :force-shell t :output :interactive))
(assert-equal 0 (run-program "true" :force-shell nil :output :interactive))
(assert-equal 1 (run-program "false" :force-shell t :output :interactive :ignore-error-status t))
(assert-equal 1 (run-program "false" :force-shell nil :output :interactive :ignore-error-status t))
;;#+allegro (trace excl:run-shell-command sys:reap-os-subprocess)
......
......@@ -247,10 +247,22 @@ return the exit status code of the process that was called.
if it was NIL, the output is discarded;
if it was :INTERACTIVE, the output and the input are inherited from the current process.
Otherwise, the output will be processed by SLURP-INPUT-STREAM,
using OUTPUT as the first argument, and return whatever it returns,
e.g. using :OUTPUT :STRING will have it return the entire output stream as a string.
Use ELEMENT-TYPE and EXTERNAL-FORMAT for the stream passed to the OUTPUT processor."
Otherwise, OUTPUT should be a value that is a suitable first argument to
SLURP-INPUT-STREAM. In this case, RUN-PROGRAM will create a temporary stream
for the program output. The program output, in that stream, will be processed
by SLURP-INPUT-STREAM, according to the using OUTPUT as the first argument.
RUN-PROGRAM will return whatever SLURP-INPUT-STREAM returns. E.g., using
:OUTPUT :STRING will have it return the entire output stream as a string. Use
ELEMENT-TYPE and EXTERNAL-FORMAT for the stream passed to the OUTPUT processor."
;; TODO: The current version does not honor :OUTPUT NIL on Allegro. Setting
;; the :INPUT and :OUTPUT arguments to RUN-SHELL-COMMAND on ACL actually do
;; what :OUTPUT :INTERACTIVE is advertised to do here. To get the behavior
;; specified for :OUTPUT NIL, one would have to grab up the process output
;; into a stream and then throw it on the floor. The consequences of
;; getting this wrong seemed so much worse than having excess output that it
;; is not currently implemented.
;; TODO: specially recognize :output pathname ?
(declare (ignorable ignore-error-status element-type external-format))
#-(or abcl allegro clisp clozure cmu cormanlisp ecl gcl lispworks mcl sbcl scl xcl)
......@@ -292,7 +304,8 @@ Use ELEMENT-TYPE and EXTERNAL-FORMAT for the stream passed to the OUTPUT process
(excl:run-shell-command
#+os-unix (coerce (cons (first command) command) 'vector)
#+os-windows command
:input interactive :output (or (and pipe :stream) interactive) :wait wait
:input nil
:output (and pipe :stream) :wait wait
#+os-windows :show-window #+os-windows (and (or (null output) pipe) :hide))
#+clisp
(flet ((run (f &rest args)
......@@ -379,13 +392,18 @@ Use ELEMENT-TYPE and EXTERNAL-FORMAT for the stream passed to the OUTPUT process
(redirected-system-command (command out)
(format nil (if (os-unix-p) "exec > ~*~A ; ~2:*~A" "~A > ~A")
(system-command command) (native-namestring out)))
;; this is only called if :OUTPUT is NIL or :INTERACTIVE
(system (command &key interactive)
(declare (ignorable interactive))
#+(or abcl xcl) (ext:run-shell-command command)
#+allegro
(excl:run-shell-command
command :input interactive :output interactive :wait t
#+os-windows :show-window #+os-windows (unless (or interactive (eq output t)) :hide))
command
:input nil
:output nil
:error-output :output ; write STDERR to output, too
:wait t
#+os-windows :show-window #+os-windows (unless (or interactive (eq output t)) :hide))
#+(or clisp clozure cmu (and lispworks os-unix) sbcl scl)
(process-result (run-program command :pipe nil :interactive interactive) nil)
#+ecl (ext:system command)
......@@ -412,6 +430,7 @@ Use ELEMENT-TYPE and EXTERNAL-FORMAT for the stream passed to the OUTPUT process
:element-type element-type
#-gcl2.6 :external-format #-gcl2.6 external-format)
(slurp-input-stream output stream)))
;; OUTPUT is either NIL (discard) or :INTERACTIVE
(call-system (system-command command) :interactive interactive)))))
(if (and (not force-shell)
#+(or clisp ecl) ignore-error-status
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment