Changeset 15397


Ignore:
Timestamp:
May 29, 2012, 9:07:06 AM (7 years ago)
Author:
gb
Message:

Windows version of RUN-PROGRAM and related functions:
RUN-PROGRAM allows its "args" argument to be a SIMPLE-STRING (as well
as a list of SIMPLE-STRINGs).

Use MAKE-WINDOWS-COMMAND-LINE (not just JOIN-STRINGS) to build the
command-line for CreateProcess? from a cons of the RUN-PROGRAM "program
name" and "args" arguments. A literal string "args" argument is passed
verbatim to the command line; the program name and any arguments in a
list-typed "args" arguments are processd by surrounding space/tab with
double-quotes and prefixing literal double-quote characters with backslash;
all other characters are passed verbatim to the command line and arguments
are separated by spaces.

This seems to be at least a first approximation of the rules used by
the MSVC runtime, though I haven't seen those rules written down
anywhere. (The program name is processed by the OS and any quoting of
it has to be done in a canonical way.)

This may fix ticket:858. How would anyone know ?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-1/linux-files.lisp

    r15232 r15397  
    17171717    "Invoke an external program as an OS subprocess of lisp."
    17181718    (declare (ignore pty))
    1719     (unless (every #'(lambda (a) (typep a 'simple-string)) args)
     1719    (push program args)
     1720    (unless (do* ((args args (cdr args)))
     1721                 ((atom args)
     1722                  (or (typep args 'simple-string)
     1723                      (null args)))
     1724              (unless (typep (car args) 'simple-string)
     1725                (return)))
    17201726      (error "Program args must all be simple strings : ~s" args))
    1721     (push program args)
    17221727    (let* ((token (list 0))
    17231728           (in-fd nil)
     
    18081813        (monitor-external-process proc))))
    18091814
    1810   (defun join-strings (strings)
    1811     (reduce (lambda (left right) (concatenate 'string left " " right)) strings))
     1815  (defun make-windows-command-line (strings)
     1816    (with-output-to-string (out)
     1817      (do* ((strings strings (cdr strings)))
     1818           ((atom strings)     
     1819            (if strings (write-string strings out)))
     1820        (let* ((string (car strings)))
     1821          (dotimes (i (length string))
     1822            (let* ((c (schar string i)))
     1823              (case c
     1824                ((#\space #\tab)
     1825                 (write-char #\" out)
     1826                 (write-char c out)
     1827                 (write-char #\" out))
     1828                (#\"
     1829                 (write-char #\\ out)
     1830                 (write-char #\" out))
     1831                (t (write-char c out)))))
     1832          (when strings (write-char #\space out))))))
    18121833
    18131834  (defun create-windows-process (new-in new-out new-err cmdstring env)
     
    18491870  (defun exec-with-io-redirection (new-in new-out new-err args proc &optional env)
    18501871    (multiple-value-bind (win handle-to-process-or-error)
    1851         (create-windows-process new-in new-out new-err (join-strings args) env)
     1872        (create-windows-process new-in new-out new-err (make-windows-command-line args) env)
    18521873      (if win
    18531874        handle-to-process-or-error
Note: See TracChangeset for help on using the changeset viewer.