Introduction
Introduction Statistics Contact Development Disclaimer Help
trun-program.lisp - clic - Clic is an command line interactive client for gophe…
git clone git://bitreich.org/clic/ git://hg6vgqziawt5s4dj.onion/clic/
Log
Files
Refs
Tags
LICENSE
---
trun-program.lisp (30529B)
---
1 ;;;; -------------------------------------------------------------------…
2 ;;;; run-program initially from xcvb-driver.
3
4 (uiop/package:define-package :uiop/run-program
5 (:nicknames :asdf/run-program) ; OBSOLETE. Used by cl-sane, printv.
6 (:use :uiop/common-lisp :uiop/package :uiop/utility :uiop/version
7 :uiop/pathname :uiop/os :uiop/filesystem :uiop/stream :uiop/launch-pr…
8 (:export
9 #:run-program
10 #:slurp-input-stream #:vomit-output-stream
11 #:subprocess-error
12 #:subprocess-error-code #:subprocess-error-command #:subprocess-error…
13 (:import-from :uiop/launch-program
14 #:%handle-if-does-not-exist #:%handle-if-exists #:%interactivep
15 #:input-stream #:output-stream #:error-output-stream))
16 (in-package :uiop/run-program)
17
18 ;;;; Slurping a stream, typically the output of another program
19 (with-upgradability ()
20 (defun call-stream-processor (fun processor stream)
21 "Given FUN (typically SLURP-INPUT-STREAM or VOMIT-OUTPUT-STREAM,
22 a PROCESSOR specification which is either an atom or a list specifying
23 a processor an keyword arguments, call the specified processor with
24 the given STREAM as input"
25 (if (consp processor)
26 (apply fun (first processor) stream (rest processor))
27 (funcall fun processor stream)))
28
29 (defgeneric slurp-input-stream (processor input-stream &key)
30 (:documentation
31 "SLURP-INPUT-STREAM is a generic function with two positional argum…
32 PROCESSOR and INPUT-STREAM and additional keyword arguments, that consum…
33 the contents of the INPUT-STREAM and processes them according to a method
34 specified by PROCESSOR.
35
36 Built-in methods include the following:
37 * if PROCESSOR is a function, it is called with the INPUT-STREAM as its …
38 * if PROCESSOR is a list, its first element should be a function. It wi…
39 INPUT-STREAM and the rest of the list. That is (x . y) will be treate…
40 \(APPLY x <stream> y\)
41 * if PROCESSOR is an output-stream, the contents of INPUT-STREAM is copi…
42 per copy-stream-to-stream, with appropriate keyword arguments.
43 * if PROCESSOR is the symbol CL:STRING or the keyword :STRING, then the …
44 are returned as a string, as per SLURP-STREAM-STRING.
45 * if PROCESSOR is the keyword :LINES then the INPUT-STREAM will be handl…
46 * if PROCESSOR is the keyword :LINE then the INPUT-STREAM will be handle…
47 * if PROCESSOR is the keyword :FORMS then the INPUT-STREAM will be handl…
48 * if PROCESSOR is the keyword :FORM then the INPUT-STREAM will be handle…
49 * if PROCESSOR is T, it is treated the same as *standard-output*. If it …
50
51 Programmers are encouraged to define their own methods for this generic …
52
53 #-genera
54 (defmethod slurp-input-stream ((function function) input-stream &key)
55 (funcall function input-stream))
56
57 (defmethod slurp-input-stream ((list cons) input-stream &key)
58 (apply (first list) input-stream (rest list)))
59
60 #-genera
61 (defmethod slurp-input-stream ((output-stream stream) input-stream
62 &key linewise prefix (element-type 'cha…
63 (copy-stream-to-stream
64 input-stream output-stream
65 :linewise linewise :prefix prefix :element-type element-type :buffe…
66
67 (defmethod slurp-input-stream ((x (eql 'string)) stream &key stripped)
68 (slurp-stream-string stream :stripped stripped))
69
70 (defmethod slurp-input-stream ((x (eql :string)) stream &key stripped)
71 (slurp-stream-string stream :stripped stripped))
72
73 (defmethod slurp-input-stream ((x (eql :lines)) stream &key count)
74 (slurp-stream-lines stream :count count))
75
76 (defmethod slurp-input-stream ((x (eql :line)) stream &key (at 0))
77 (slurp-stream-line stream :at at))
78
79 (defmethod slurp-input-stream ((x (eql :forms)) stream &key count)
80 (slurp-stream-forms stream :count count))
81
82 (defmethod slurp-input-stream ((x (eql :form)) stream &key (at 0))
83 (slurp-stream-form stream :at at))
84
85 (defmethod slurp-input-stream ((x (eql t)) stream &rest keys &key &all…
86 (apply 'slurp-input-stream *standard-output* stream keys))
87
88 (defmethod slurp-input-stream ((x null) (stream t) &key)
89 nil)
90
91 (defmethod slurp-input-stream ((pathname pathname) input
92 &key
93 (element-type *default-stream-element…
94 (external-format *utf-8-external-form…
95 (if-exists :rename-and-delete)
96 (if-does-not-exist :create)
97 buffer-size
98 linewise)
99 (with-output-file (output pathname
100 :element-type element-type
101 :external-format external-format
102 :if-exists if-exists
103 :if-does-not-exist if-does-not-exist)
104 (copy-stream-to-stream
105 input output
106 :element-type element-type :buffer-size buffer-size :linewise lin…
107
108 (defmethod slurp-input-stream (x stream
109 &key linewise prefix (element-type 'cha…
110 (declare (ignorable stream linewise prefix element-type buffer-size))
111 (cond
112 #+genera
113 ((functionp x) (funcall x stream))
114 #+genera
115 ((output-stream-p x)
116 (copy-stream-to-stream
117 stream x
118 :linewise linewise :prefix prefix :element-type element-type :bu…
119 (t
120 (parameter-error "Invalid ~S destination ~S" 'slurp-input-stream …
121
122 ;;;; Vomiting a stream, typically into the input of another program.
123 (with-upgradability ()
124 (defgeneric vomit-output-stream (processor output-stream &key)
125 (:documentation
126 "VOMIT-OUTPUT-STREAM is a generic function with two positional argu…
127 PROCESSOR and OUTPUT-STREAM and additional keyword arguments, that produ…
128 some content onto the OUTPUT-STREAM, according to a method specified by …
129
130 Built-in methods include the following:
131 * if PROCESSOR is a function, it is called with the OUTPUT-STREAM as its…
132 * if PROCESSOR is a list, its first element should be a function.
133 It will be applied to a cons of the OUTPUT-STREAM and the rest of the …
134 That is (x . y) will be treated as \(APPLY x <stream> y\)
135 * if PROCESSOR is an input-stream, its contents will be copied the OUTPU…
136 per copy-stream-to-stream, with appropriate keyword arguments.
137 * if PROCESSOR is a string, its contents will be printed to the OUTPUT-S…
138 * if PROCESSOR is T, it is treated the same as *standard-input*. If it i…
139
140 Programmers are encouraged to define their own methods for this generic …
141
142 #-genera
143 (defmethod vomit-output-stream ((function function) output-stream &key)
144 (funcall function output-stream))
145
146 (defmethod vomit-output-stream ((list cons) output-stream &key)
147 (apply (first list) output-stream (rest list)))
148
149 #-genera
150 (defmethod vomit-output-stream ((input-stream stream) output-stream
151 &key linewise prefix (element-type 'cha…
152 (copy-stream-to-stream
153 input-stream output-stream
154 :linewise linewise :prefix prefix :element-type element-type :buffe…
155
156 (defmethod vomit-output-stream ((x string) stream &key fresh-line terp…
157 (princ x stream)
158 (when fresh-line (fresh-line stream))
159 (when terpri (terpri stream))
160 (values))
161
162 (defmethod vomit-output-stream ((x (eql t)) stream &rest keys &key &al…
163 (apply 'vomit-output-stream *standard-input* stream keys))
164
165 (defmethod vomit-output-stream ((x null) (stream t) &key)
166 (values))
167
168 (defmethod vomit-output-stream ((pathname pathname) input
169 &key
170 (element-type *default-stream-element…
171 (external-format *utf-8-external-form…
172 (if-exists :rename-and-delete)
173 (if-does-not-exist :create)
174 buffer-size
175 linewise)
176 (with-output-file (output pathname
177 :element-type element-type
178 :external-format external-format
179 :if-exists if-exists
180 :if-does-not-exist if-does-not-exist)
181 (copy-stream-to-stream
182 input output
183 :element-type element-type :buffer-size buffer-size :linewise lin…
184
185 (defmethod vomit-output-stream (x stream
186 &key linewise prefix (element-type 'cha…
187 (declare (ignorable stream linewise prefix element-type buffer-size))
188 (cond
189 #+genera
190 ((functionp x) (funcall x stream))
191 #+genera
192 ((input-stream-p x)
193 (copy-stream-to-stream
194 x stream
195 :linewise linewise :prefix prefix :element-type element-type :bu…
196 (t
197 (parameter-error "Invalid ~S source ~S" 'vomit-output-stream x)))…
198
199
200 ;;;; Run-program: synchronously run a program in a subprocess, handling …
201 (with-upgradability ()
202 (define-condition subprocess-error (error)
203 ((code :initform nil :initarg :code :reader subprocess-error-code)
204 (command :initform nil :initarg :command :reader subprocess-error-c…
205 (process :initform nil :initarg :process :reader subprocess-error-p…
206 (:report (lambda (condition stream)
207 (format stream "Subprocess ~@[~S~% ~]~@[with command ~S~%…
208 (subprocess-error-process condition)
209 (subprocess-error-command condition)
210 (subprocess-error-code condition)))))
211
212 (defun %check-result (exit-code &key command process ignore-error-stat…
213 (unless ignore-error-status
214 (unless (eql exit-code 0)
215 (cerror "IGNORE-ERROR-STATUS"
216 'subprocess-error :command command :code exit-code :proc…
217 exit-code)
218
219 (defun %active-io-specifier-p (specifier)
220 "Determines whether a run-program I/O specifier requires Lisp-side p…
221 via SLURP-INPUT-STREAM or VOMIT-OUTPUT-STREAM (return T),
222 or whether it's already taken care of by the implementation's underlying…
223 (not (typep specifier '(or null string pathname (member :interactive…
224 #+(or cmucl (and sbcl os-unix) scl) (or stre…
225 #+lispworks file-stream))))
226
227 (defun %run-program (command &rest keys &key &allow-other-keys)
228 "DEPRECATED. Use LAUNCH-PROGRAM instead."
229 (apply 'launch-program command keys))
230
231 (defun %call-with-program-io (gf tval stream-easy-p fun direction spec…
232 &key
233 (element-type #-clozure *default-strea…
234 (external-format *utf-8-external-forma…
235 ;; handle redirection for run-program and system
236 ;; SPEC is the specification for the subprocess's input or output or…
237 ;; TVAL is the value used if the spec is T
238 ;; GF is the generic function to call to handle arbitrary values of …
239 ;; STREAM-EASY-P is T if we're going to use a RUN-PROGRAM that copie…
240 ;; (it's only meaningful on CMUCL, SBCL, SCL that actually do it)
241 ;; DIRECTION is :INPUT, :OUTPUT or :ERROR-OUTPUT for the direction o…
242 ;; FUN is a function of the new reduced spec and an activity functio…
243 ;; when the subprocess is active and communicating through that stre…
244 ;; ACTIVEP is a boolean true if we will get to run code while the pr…
245 ;; ELEMENT-TYPE and EXTERNAL-FORMAT control what kind of temporary f…
246 ;; RETURNER is a function called with the value of the activity.
247 ;; --- TODO ([email protected]): handle if-output-exists and such when …
248 (declare (ignorable stream-easy-p))
249 (let* ((actual-spec (if (eq spec t) tval spec))
250 (activity-spec (if (eq actual-spec :output)
251 (ecase direction
252 ((:input :output)
253 (parameter-error "~S does not allow ~S …
254 'run-program :output d…
255 ((:error-output)
256 nil))
257 actual-spec)))
258 (labels ((activity (stream)
259 (call-function returner (call-stream-processor gf activ…
260 (easy-case ()
261 (funcall fun actual-spec nil))
262 (hard-case ()
263 (if activep
264 (funcall fun :stream #'activity)
265 (with-temporary-file (:pathname tmp)
266 (ecase direction
267 (:input
268 (with-output-file (s tmp :if-exists :overwrite
269 :external-format external…
270 :element-type element-typ…
271 (activity s))
272 (funcall fun tmp nil))
273 ((:output :error-output)
274 (multiple-value-prog1 (funcall fun tmp nil)
275 (with-input-file (s tmp
276 :external-format external…
277 :element-type element-typ…
278 (activity s)))))))))
279 (typecase activity-spec
280 ((or null string pathname (eql :interactive))
281 (easy-case))
282 #+(or cmucl (and sbcl os-unix) scl) ;; streams are only easy o…
283 (stream
284 (if stream-easy-p (easy-case) (hard-case)))
285 (t
286 (hard-case))))))
287
288 (defmacro place-setter (place)
289 (when place
290 (let ((value (gensym)))
291 `#'(lambda (,value) (setf ,place ,value)))))
292
293 (defmacro with-program-input (((reduced-input-var
294 &optional (input-activity-var (gensym)…
295 input-form &key setf stream-easy-p acti…
296 `(apply '%call-with-program-io 'vomit-output-stream *standard-input*…
297 #'(lambda (,reduced-input-var ,input-activity-var)
298 ,@(unless iavp `((declare (ignore ,input-activity-var))))
299 ,@body)
300 :input ,input-form ,active (place-setter ,setf) ,keys))
301
302 (defmacro with-program-output (((reduced-output-var
303 &optional (output-activity-var (gensym…
304 output-form &key setf stream-easy-p ac…
305 `(apply '%call-with-program-io 'slurp-input-stream *standard-output*…
306 #'(lambda (,reduced-output-var ,output-activity-var)
307 ,@(unless oavp `((declare (ignore ,output-activity-var))…
308 ,@body)
309 :output ,output-form ,active (place-setter ,setf) ,keys))
310
311 (defmacro with-program-error-output (((reduced-error-output-var
312 &optional (error-output-activit…
313 error-output-form &key setf stre…
314 &body body)
315 `(apply '%call-with-program-io 'slurp-input-stream *error-output* ,s…
316 #'(lambda (,reduced-error-output-var ,error-output-activity-…
317 ,@(unless eoavp `((declare (ignore ,error-output-activit…
318 ,@body)
319 :error-output ,error-output-form ,active (place-setter ,setf…
320
321 (defun %use-launch-program (command &rest keys
322 &key input output error-output ignore-error-s…
323 ;; helper for RUN-PROGRAM when using LAUNCH-PROGRAM
324 #+(or cormanlisp gcl (and lispworks os-windows) mcl xcl)
325 (progn
326 command keys input output error-output ignore-error-status ;; igno…
327 (not-implemented-error '%use-launch-program))
328 (when (member :stream (list input output error-output))
329 (parameter-error "~S: ~S is not allowed as synchronous I/O redirec…
330 'run-program :stream))
331 (let* ((active-input-p (%active-io-specifier-p input))
332 (active-output-p (%active-io-specifier-p output))
333 (active-error-output-p (%active-io-specifier-p error-output))
334 (activity
335 (cond
336 (active-output-p :output)
337 (active-input-p :input)
338 (active-error-output-p :error-output)
339 (t nil)))
340 output-result error-output-result exit-code process-info)
341 (with-program-output ((reduced-output output-activity)
342 output :keys keys :setf output-result
343 :stream-easy-p t :active (eq activity :outpu…
344 (with-program-error-output ((reduced-error-output error-output-a…
345 error-output :keys keys :setf error-…
346 :stream-easy-p t :active (eq activit…
347 (with-program-input ((reduced-input input-activity)
348 input :keys keys
349 :stream-easy-p t :active (eq activity :in…
350 (setf process-info
351 (apply 'launch-program command
352 :input reduced-input :output reduced-output
353 :error-output (if (eq error-output :output) :ou…
354 keys))
355 (labels ((get-stream (stream-name &optional fallbackp)
356 (or (slot-value process-info stream-name)
357 (when fallbackp
358 (slot-value process-info 'bidir-stream))))
359 (run-activity (activity stream-name &optional fallb…
360 (if-let (stream (get-stream stream-name fallbackp…
361 (funcall activity stream)
362 (error 'subprocess-error
363 :code `(:missing ,stream-name)
364 :command command :process process-info))…
365 (unwind-protect
366 (ecase activity
367 ((nil))
368 (:input (run-activity input-activity 'input-stream …
369 (:output (run-activity output-activity 'output-stre…
370 (:error-output (run-activity error-output-activity …
371 (close-streams process-info)
372 (setf exit-code (wait-process process-info)))))))
373 (%check-result exit-code
374 :command command :process process-info
375 :ignore-error-status ignore-error-status)
376 (values output-result error-output-result exit-code)))
377
378 (defun %normalize-system-command (command) ;; helper for %USE-SYSTEM
379 (etypecase command
380 (string command)
381 (list (escape-shell-command
382 (os-cond
383 ((os-unix-p) (cons "exec" command))
384 (t command))))))
385
386 (defun %redirected-system-command (command in out err directory) ;; he…
387 (flet ((redirect (spec operator)
388 (let ((pathname
389 (typecase spec
390 (null (null-device-pathname))
391 (string (parse-native-namestring spec))
392 (pathname spec)
393 ((eql :output)
394 (unless (equal operator " 2>>")
395 (parameter-error "~S: only the ~S argument can…
396 'run-program :error-output :o…
397 (return-from redirect '(" 2>&1"))))))
398 (when pathname
399 (list operator " "
400 (escape-shell-token (native-namestring pathname))…
401 (let* ((redirections (append (redirect in " <") (redirect out " >>…
402 (normalized (%normalize-system-command command))
403 (directory (or directory #+(or abcl xcl) (getcwd)))
404 (chdir (when directory
405 (let ((dir-arg (escape-shell-token (native-namestr…
406 (os-cond
407 ((os-unix-p) `("cd " ,dir-arg " ; "))
408 ((os-windows-p) `("cd /d " ,dir-arg " & ")))))))
409 (reduce/strcat
410 (os-cond
411 ((os-unix-p) `(,@(when redirections `("exec " ,@redirections "…
412 ((os-windows-p) `(,@redirections " (" ,@chdir ,normalized ")")…
413
414 (defun %system (command &rest keys &key directory
415 input (if-input-does-not-exist :e…
416 output (if-output-exists :superse…
417 error-output (if-error-output-exi…
418 &allow-other-keys)
419 "A portable abstraction of a low-level call to libc's system()."
420 (declare (ignorable keys directory input if-input-does-not-exist out…
421 if-output-exists error-output if-error-output-ex…
422 (when (member :stream (list input output error-output))
423 (parameter-error "~S: ~S is not allowed as synchronous I/O redirec…
424 'run-program :stream))
425 #+(or abcl allegro clozure cmucl ecl (and lispworks os-unix) mkcl sb…
426 (let (#+(or abcl ecl mkcl)
427 (version (parse-version
428 #-abcl
429 (lisp-implementation-version)
430 #+abcl
431 (second (split-string (implementation-identifier) …
432 (nest
433 #+abcl (unless (lexicographic< '< version '(1 4 0)))
434 #+ecl (unless (lexicographic<= '< version '(16 0 0)))
435 #+mkcl (unless (lexicographic<= '< version '(1 1 9)))
436 (return-from %system
437 (wait-process
438 (apply 'launch-program (%normalize-system-command command) key…
439 #+(or abcl clasp clisp cormanlisp ecl gcl genera (and lispworks os-w…
440 (let ((%command (%redirected-system-command command input output err…
441 ;; see comments for these functions
442 (%handle-if-does-not-exist input if-input-does-not-exist)
443 (%handle-if-exists output if-output-exists)
444 (%handle-if-exists error-output if-error-output-exists)
445 #+abcl (ext:run-shell-command %command)
446 #+(or clasp ecl) (let ((*standard-input* *stdin*)
447 (*standard-output* *stdout*)
448 (*error-output* *stderr*))
449 (ext:system %command))
450 #+clisp
451 (let ((raw-exit-code
452 (or
453 #.`(#+os-windows ,@'(ext:run-shell-command %command)
454 #+os-unix ,@'(ext:run-program "/bin/sh" :arguments `("…
455 :wait t :input :terminal :output :terminal)
456 0)))
457 (if (minusp raw-exit-code)
458 (- 128 raw-exit-code)
459 raw-exit-code))
460 #+cormanlisp (win32:system %command)
461 #+gcl (system:system %command)
462 #+genera (not-implemented-error '%system)
463 #+(and lispworks os-windows)
464 (system:call-system %command :current-directory directory :wait t)
465 #+mcl (ccl::with-cstrs ((%%command %command)) (_system %%command))
466 #+mkcl (mkcl:system %command)
467 #+xcl (system:%run-shell-command %command)))
468
469 (defun %use-system (command &rest keys
470 &key input output error-output ignore-error-status…
471 ;; helper for RUN-PROGRAM when using %system
472 (let (output-result error-output-result exit-code)
473 (with-program-output ((reduced-output)
474 output :keys keys :setf output-result)
475 (with-program-error-output ((reduced-error-output)
476 error-output :keys keys :setf error-…
477 (with-program-input ((reduced-input) input :keys keys)
478 (setf exit-code (apply '%system command
479 :input reduced-input :output reduced-…
480 :error-output reduced-error-output ke…
481 (%check-result exit-code
482 :command command
483 :ignore-error-status ignore-error-status)
484 (values output-result error-output-result exit-code)))
485
486 (defun run-program (command &rest keys
487 &key ignore-error-status (force-shell nil force-s…
488 input (if-input-does-not-exist :error)
489 output (if-output-exists :supersede)
490 error-output (if-error-output-exists :supersede)
491 (element-type #-clozure *default-stream-element…
492 (external-format *utf-8-external-format*)
493 &allow-other-keys)
494 "Run program specified by COMMAND,
495 either a list of strings specifying a program and list of arguments,
496 or a string specifying a shell command (/bin/sh on Unix, CMD.EXE on Wind…
497 _synchronously_ process its output as specified and return the processin…
498 when the program and its output processing are complete.
499
500 Always call a shell (rather than directly execute the command when possi…
501 if FORCE-SHELL is specified. Similarly, never call a shell if FORCE-SHE…
502 specified to be NIL.
503
504 Signal a continuable SUBPROCESS-ERROR if the process wasn't successful (…
505 unless IGNORE-ERROR-STATUS is specified.
506
507 If OUTPUT is a pathname, a string designating a pathname, or NIL (the de…
508 designating the null device, the file at that path is used as output.
509 If it's :INTERACTIVE, output is inherited from the current process;
510 beware that this may be different from your *STANDARD-OUTPUT*,
511 and under SLIME will be on your *inferior-lisp* buffer.
512 If it's T, output goes to your current *STANDARD-OUTPUT* stream.
513 Otherwise, OUTPUT should be a value that is a suitable first argument to
514 SLURP-INPUT-STREAM (qv.), or a list of such a value and keyword argument…
515 In this case, RUN-PROGRAM will create a temporary stream for the program…
516 the program output, in that stream, will be processed by a call to SLURP…
517 using OUTPUT as the first argument (or the first element of OUTPUT, and …
518 The primary value resulting from that call (or NIL if no call was needed)
519 will be the first value returned by RUN-PROGRAM.
520 E.g., using :OUTPUT :STRING will have it return the entire output stream…
521 And using :OUTPUT '(:STRING :STRIPPED T) will have it return the same st…
522 stripped of any ending newline.
523
524 IF-OUTPUT-EXISTS, which is only meaningful if OUTPUT is a string or a
525 pathname, can take the values :ERROR, :APPEND, and :SUPERSEDE (the
526 default). The meaning of these values and their effect on the case
527 where OUTPUT does not exist, is analogous to the IF-EXISTS parameter
528 to OPEN with :DIRECTION :OUTPUT.
529
530 ERROR-OUTPUT is similar to OUTPUT, except that the resulting value is re…
531 as the second value of RUN-PROGRAM. T designates the *ERROR-OUTPUT*.
532 Also :OUTPUT means redirecting the error output to the output stream,
533 in which case NIL is returned.
534
535 IF-ERROR-OUTPUT-EXISTS is similar to IF-OUTPUT-EXIST, except that it
536 affects ERROR-OUTPUT rather than OUTPUT.
537
538 INPUT is similar to OUTPUT, except that VOMIT-OUTPUT-STREAM is used,
539 no value is returned, and T designates the *STANDARD-INPUT*.
540
541 IF-INPUT-DOES-NOT-EXIST, which is only meaningful if INPUT is a string
542 or a pathname, can take the values :CREATE and :ERROR (the
543 default). The meaning of these values is analogous to the
544 IF-DOES-NOT-EXIST parameter to OPEN with :DIRECTION :INPUT.
545
546 ELEMENT-TYPE and EXTERNAL-FORMAT are passed on
547 to your Lisp implementation, when applicable, for creation of the output…
548
549 One and only one of the stream slurping or vomiting may or may not happen
550 in parallel in parallel with the subprocess,
551 depending on options and implementation,
552 and with priority being given to output processing.
553 Other streams are completely produced or consumed
554 before or after the subprocess is spawned, using temporary files.
555
556 RUN-PROGRAM returns 3 values:
557 0- the result of the OUTPUT slurping if any, or NIL
558 1- the result of the ERROR-OUTPUT slurping if any, or NIL
559 2- either 0 if the subprocess exited with success status,
560 or an indication of failure via the EXIT-CODE of the process"
561 (declare (ignorable input output error-output if-input-does-not-exis…
562 if-error-output-exists element-type external-for…
563 #-(or abcl allegro clasp clisp clozure cmucl cormanlisp ecl gcl lisp…
564 (not-implemented-error 'run-program)
565 (apply (if (or force-shell
566 ;; Per doc string, set FORCE-SHELL to T if we get com…
567 ;; But don't override user's specified preference. [2…
568 (and (stringp command)
569 (or (not force-shell-suppliedp)
570 #-(or allegro clisp clozure sbcl) (os-cond (…
571 #+(or clasp clisp cormanlisp gcl (and lispworks os-wi…
572 ;; A race condition in ECL <= 16.0.0 prevents using e…
573 #+ecl #.(if-let (ver (parse-version (lisp-implementat…
574 (lexicographic<= '< ver '(16 0 0)))
575 #+(and lispworks os-unix) (%interactivep input output…
576 '%use-system '%use-launch-program)
577 command keys)))
578
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.