comparison lisp/process.el @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
1 ;;; process.el --- commands for subprocesses; split out of simple.el 1 ;;; process.el --- commands for subprocesses; split out of simple.el
2 2
3 ;; Copyright (C) 1985-7, 1993,4, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985-7, 1993,4, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995 Ben Wing. 4 ;; Copyright (C) 1995, 2000 Ben Wing.
5 5
6 ;; Author: Ben Wing 6 ;; Author: Ben Wing
7 ;; Maintainer: XEmacs Development Team 7 ;; Maintainer: XEmacs Development Team
8 ;; Keywords: internal, processes, dumped 8 ;; Keywords: internal, processes, dumped
9 9
23 ;; along with XEmacs; see the file COPYING. If not, write to the 23 ;; along with XEmacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, 59 Temple Place - Suite 330, 24 ;; Free Software Foundation, 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA. 25 ;; Boston, MA 02111-1307, USA.
26 26
27 ;;; Synched up with: FSF 19.30. 27 ;;; Synched up with: FSF 19.30.
28
29 ;;; Authorship:
30
31 ;; Created 1995 by Ben Wing during Mule work -- some commands split out
32 ;; of simple.el and wrappers of *-internal functions created so they could
33 ;; be redefined in a Mule world.
34 ;; Lisp definition of call-process-internal added Mar. 2000 by Ben Wing.
28 35
29 ;;; Commentary: 36 ;;; Commentary:
30 37
31 ;; This file is dumped with XEmacs. 38 ;; This file is dumped with XEmacs.
32 39
64 Wildcards and redirection are handled as usual in the shell." 71 Wildcards and redirection are handled as usual in the shell."
65 ;; We used to use `exec' to replace the shell with the command, 72 ;; We used to use `exec' to replace the shell with the command,
66 ;; but that failed to handle (...) and semicolon, etc. 73 ;; but that failed to handle (...) and semicolon, etc.
67 (start-process name buffer shell-file-name shell-command-switch 74 (start-process name buffer shell-file-name shell-command-switch
68 (mapconcat #'identity args " "))) 75 (mapconcat #'identity args " ")))
76
77 (defun call-process-internal (program &optional infile buffer display &rest args)
78 "Call PROGRAM synchronously in separate process, with coding-system specified.
79 Arguments are
80 (PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS).
81 The program's input comes from file INFILE (nil means `/dev/null').
82 Insert output in BUFFER before point; t means current buffer;
83 nil for BUFFER means discard it; 0 means discard and don't wait.
84 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
85 REAL-BUFFER says what to do with standard output, as above,
86 while STDERR-FILE says what to do with standard error in the child.
87 STDERR-FILE may be nil (discard standard error output),
88 t (mix it with ordinary output), or a file name string.
89
90 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
91 Remaining arguments are strings passed as command arguments to PROGRAM.
92
93 If BUFFER is 0, `call-process' returns immediately with value nil.
94 Otherwise it waits for PROGRAM to terminate and returns a numeric exit status
95 or a signal description string.
96 If you quit, the process is killed with SIGINT, or SIGKILL if you
97 quit again."
98 ;; #### remove windows-nt check when this is ready for prime time.
99 (if (or (noninteractive) (not (eq 'windows-nt system-type)))
100 (apply 'old-call-process-internal program infile buffer display args)
101 (let (proc inbuf errbuf discard)
102 (unwind-protect
103 (progn
104 (when infile
105 (setq infile (expand-file-name infile))
106 (setq inbuf (generate-new-buffer "*call-process*"))
107 (with-current-buffer inbuf
108 ;; Make sure this works with jka-compr
109 (let ((file-name-handler-alist nil))
110 (insert-file-contents-internal infile nil nil nil nil
111 'binary))))
112 (let ((stderr (if (consp buffer) (second buffer) t)))
113 (if (consp buffer) (setq buffer (car buffer)))
114 (setq buffer
115 (cond ((null buffer) nil)
116 ((eq buffer t) (current-buffer))
117 ;; use integerp for compatibility with existing
118 ;; call-process rmsism.
119 ((integerp buffer) (setq discard t) nil)
120 (t (get-buffer-create buffer))))
121 (when (and stderr (not (eq t stderr)))
122 (setq stderr (expand-file-name stderr))
123 (setq errbuf (generate-new-buffer "*call-process*")))
124 (setq proc
125 (apply 'start-process-internal "*call-process*"
126 buffer
127 ;#### not implemented until my new process
128 ;changes go in.
129 ;(if (eq t stderr) buffer (list buffer errbuf))
130 program args))
131 (if buffer
132 (set-marker (process-mark proc) (point buffer) buffer))
133 (unwind-protect
134 (prog1
135 (catch 'call-process-done
136 (when (not discard)
137 (set-process-sentinel
138 proc
139 #'(lambda (proc status)
140 (cond ((eq 'exit (process-status proc))
141 (set-process-sentinel proc nil)
142 (throw 'call-process-done
143 (process-exit-status proc)))
144 ((eq 'signal (process-status proc))
145 (set-process-sentinel proc nil)
146 (throw 'call-process-done status))))))
147 (when inbuf
148 (process-send-region proc 1
149 (1+ (buffer-size inbuf)) inbuf))
150 (process-send-eof proc)
151 (when discard
152 ;; we're trying really really hard to emulate
153 ;; the old call-process.
154 (if errbuf
155 (set-process-sentinel
156 proc
157 `(lambda (proc status)
158 (write-region-internal
159 1 (1+ (buffer-size))
160 ,stderr
161 nil 'major-rms-kludge-city nil
162 coding-system-for-write))))
163 (setq errbuf nil)
164 (setq proc nil)
165 (throw 'call-process-done nil))
166 (while t
167 (accept-process-output proc)
168 (if display (sit-for 0))))
169 (when errbuf
170 (with-current-buffer errbuf
171 (write-region-internal 1 (1+ (buffer-size)) stderr
172 nil 'major-rms-kludge-city nil
173 coding-system-for-write))))
174 (if proc (set-process-sentinel proc nil)))))
175 (if inbuf (kill-buffer inbuf))
176 (if errbuf (kill-buffer errbuf))
177 (condition-case nil
178 (if (and proc (process-live-p proc)) (kill-process proc))
179 (error nil))))))
69 180
70 (defun call-process (program &optional infile buffer displayp &rest args) 181 (defun call-process (program &optional infile buffer displayp &rest args)
71 "Call PROGRAM synchronously in separate process. 182 "Call PROGRAM synchronously in separate process.
72 The program's input comes from file INFILE (nil means `/dev/null'). 183 The program's input comes from file INFILE (nil means `/dev/null').
73 Insert output in BUFFER before point; t means current buffer; 184 Insert output in BUFFER before point; t means current buffer;
308 specifying a port number to connect to. 419 specifying a port number to connect to.
309 Fifth argument PROTOCOL is a network protocol. Currently 'tcp 420 Fifth argument PROTOCOL is a network protocol. Currently 'tcp
310 (Transmission Control Protocol) and 'udp (User Datagram Protocol) are 421 (Transmission Control Protocol) and 'udp (User Datagram Protocol) are
311 supported. When omitted, 'tcp is assumed. 422 supported. When omitted, 'tcp is assumed.
312 423
313 Ouput via `process-send-string' and input via buffer or filter (see 424 Output via `process-send-string' and input via buffer or filter (see
314 `set-process-filter') are stream-oriented. That means UDP datagrams are 425 `set-process-filter') are stream-oriented. That means UDP datagrams are
315 not guaranteed to be sent and received in discrete packets. (But small 426 not guaranteed to be sent and received in discrete packets. (But small
316 datagrams around 500 bytes that are not truncated by `process-send-string' 427 datagrams around 500 bytes that are not truncated by `process-send-string'
317 are usually fine.) Note further that UDP protocol does not guard against 428 are usually fine.) Note further that UDP protocol does not guard against
318 lost packets." 429 lost packets."
319 (open-network-stream-internal name buffer host service protocol)) 430 (open-network-stream-internal name buffer host service protocol))
320 431
321 (defun shell-quote-argument (argument) 432 (defun shell-quote-argument (argument)
322 "Quote an argument for passing as argument to an inferior shell." 433 "Quote an argument for passing as argument to an inferior shell."
323 (if (eq system-type 'windows-nt) 434 (if (and (eq system-type 'windows-nt)
324 (nt-quote-process-args (list shell-file-name argument)) 435 (let ((progname (downcase (file-name-nondirectory
436 shell-file-name))))
437 (or (equal progname "command.com")
438 (equal progname "cmd.exe"))))
439 ;; the expectation is that you can take the result of
440 ;; shell-quote-argument and pass it to as an arg to
441 ;; (start-process shell-quote-argument ...) and have it end
442 ;; up as-is in the program's argv[] array. to do this, we
443 ;; need to protect against both the shell's and the program's
444 ;; quoting conventions (and our own conventions in
445 ;; mswindows-construct-process-command-line!). Putting quotes
446 ;; around shell metachars gets through the last two, and applying
447 ;; the normal VC runtime quoting works with practically all apps.
448 (mswindows-quote-one-vc-runtime-arg argument t)
325 ;; Quote everything except POSIX filename characters. 449 ;; Quote everything except POSIX filename characters.
326 ;; This should be safe enough even for really weird shells. 450 ;; This should be safe enough even for really weird shells.
327 (let ((result "") (start 0) end) 451 (let ((result "") (start 0) end)
328 (while (string-match "[^-0-9a-zA-Z_./]" argument start) 452 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
329 (setq end (match-beginning 0) 453 (setq end (match-beginning 0)