sys.lisp: New toy for running external programs.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 22 Dec 2014 22:19:17 +0000 (22:19 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 22 Dec 2014 22:23:09 +0000 (22:23 +0000)
sys.lisp

index 10cd5ca..d3dfc08 100644 (file)
--- a/sys.lisp
+++ b/sys.lisp
    `temporary-file'."
   `(with-temporary-files* (lambda (,context) ,@body) ,base))
 
+(export 'run-program)
+(defun run-program (command &key input output)
+  "Run a COMMAND, specified as a list of arguments.
+
+   The INPUT and OUTPUT may be `nil' (no input, discard output), or
+   pathnames or namestrings.  Signals an error if the command fails."
+
+  #+ sbcl
+  (let ((proc (sb-ext:run-program (car command) (cdr command)
+                                 :wait t :search t
+                                 :input input :output output :error t
+                                 :if-input-does-not-exist :error
+                                 :if-output-exists :supersede)))
+    (unless (and (eq (sb-ext:process-status proc) :exited)
+                (zerop (sb-ext:process-exit-code proc)))
+      (error "Failed to run command `~{~A~^ ~}': ~S ~S" command
+            (sb-ext:process-status proc) (sb-ext:process-exit-code proc))))
+
+  #+ clisp
+  (let ((rc (ext:run-program (car command) :arguments (cdr command)
+                            :input input :output output
+                            :if-output-exists :overwrite)))
+    (when rc
+      (error "Failed to run command `~{~A~^ ~}': status ~S" command rc))))
+
 ;;;----- That's all, folks --------------------------------------------------