Skip to content
Snippets Groups Projects
Commit 6510db1e authored by Robert P. Goldman's avatar Robert P. Goldman
Browse files

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
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment