comparison lisp/process.el @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 11054d720c21
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
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, 2000 Ben Wing. 4 ;; Copyright (C) 1995 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
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 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.
35
36 ;;; Commentary: 29 ;;; Commentary:
37 30
38 ;; This file is dumped with XEmacs. 31 ;; This file is dumped with XEmacs.
39 32
40 ;;; Code: 33 ;;; Code:
41 34
42 35
36 (defvar binary-process-output)
37 (defvar buffer-file-type)
38
43 (defgroup processes nil 39 (defgroup processes nil
44 "Process, subshell, compilation, and job control support." 40 "Process, subshell, compilation, and job control support."
45 :group 'external 41 :group 'external
46 :group 'development) 42 :group 'development)
47 43
72 ;; We used to use `exec' to replace the shell with the command, 68 ;; We used to use `exec' to replace the shell with the command,
73 ;; but that failed to handle (...) and semicolon, etc. 69 ;; but that failed to handle (...) and semicolon, etc.
74 (start-process name buffer shell-file-name shell-command-switch 70 (start-process name buffer shell-file-name shell-command-switch
75 (mapconcat #'identity args " "))) 71 (mapconcat #'identity args " ")))
76 72
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))))))
180
181 (defun call-process (program &optional infile buffer displayp &rest args) 73 (defun call-process (program &optional infile buffer displayp &rest args)
182 "Call PROGRAM synchronously in separate process. 74 "Call PROGRAM synchronously in separate process.
183 The program's input comes from file INFILE (nil means `/dev/null'). 75 The program's input comes from file INFILE (nil means `/dev/null').
184 Insert output in BUFFER before point; t means current buffer; 76 Insert output in BUFFER before point; t means current buffer;
185 nil for BUFFER means discard it; 0 means discard and don't wait. 77 nil for BUFFER means discard it; 0 means discard and don't wait.
221 and returns a numeric exit status or a signal description string. 113 and returns a numeric exit status or a signal description string.
222 If you quit, the process is first killed with SIGINT, then with SIGKILL if 114 If you quit, the process is first killed with SIGINT, then with SIGKILL if
223 you quit again before the process exits." 115 you quit again before the process exits."
224 (let ((temp 116 (let ((temp
225 (make-temp-name 117 (make-temp-name
226 (concat (file-name-as-directory (temp-directory)) "emacs")))) 118 (concat (file-name-as-directory (temp-directory))
119 (if (memq system-type '(ms-dos windows-nt)) "em" "emacs")))))
227 (unwind-protect 120 (unwind-protect
228 (progn 121 (progn
229 (write-region start end temp nil 'silent) 122 (if (memq system-type '(ms-dos windows-nt))
123 (let ((buffer-file-type binary-process-output))
124 (write-region start end temp nil 'silent))
125 (write-region start end temp nil 'silent))
230 (if deletep (delete-region start end)) 126 (if deletep (delete-region start end))
231 (apply #'call-process program temp buffer displayp args)) 127 (apply #'call-process program temp buffer displayp args))
232 (ignore-file-errors (delete-file temp))))) 128 (ignore-file-errors (delete-file temp)))))
233 129
234 130
401 with any buffer 297 with any buffer
402 Third arg is program file name. It is searched for as in the shell. 298 Third arg is program file name. It is searched for as in the shell.
403 Remaining arguments are strings to give program as arguments." 299 Remaining arguments are strings to give program as arguments."
404 (apply 'start-process-internal name buffer program program-args)) 300 (apply 'start-process-internal name buffer program program-args))
405 301
406 (defun open-network-stream (name buffer host service &optional protocol) 302 (defun open-network-stream (name buffer host service)
407 "Open a TCP connection for a service to a host. 303 "Open a TCP connection for a service to a host.
408 Returns a subprocess-object to represent the connection. 304 Returns a subprocess-object to represent the connection.
409 Input and output work as for subprocesses; `delete-process' closes it. 305 Input and output work as for subprocesses; `delete-process' closes it.
410 Args are NAME BUFFER HOST SERVICE. 306 Args are NAME BUFFER HOST SERVICE.
411 NAME is name for process. It is modified if necessary to make it unique. 307 NAME is name for process. It is modified if necessary to make it unique.
414 an output stream or filter function to handle the output. 310 an output stream or filter function to handle the output.
415 BUFFER may be also nil, meaning that this process is not associated 311 BUFFER may be also nil, meaning that this process is not associated
416 with any buffer 312 with any buffer
417 Third arg is name of the host to connect to, or its IP address. 313 Third arg is name of the host to connect to, or its IP address.
418 Fourth arg SERVICE is name of the service desired, or an integer 314 Fourth arg SERVICE is name of the service desired, or an integer
419 specifying a port number to connect to. 315 specifying a port number to connect to."
420 Fifth argument PROTOCOL is a network protocol. Currently 'tcp 316 (open-network-stream-internal name buffer host service))
421 (Transmission Control Protocol) and 'udp (User Datagram Protocol) are
422 supported. When omitted, 'tcp is assumed.
423
424 Ouput via `process-send-string' and input via buffer or filter (see
425 `set-process-filter') are stream-oriented. That means UDP datagrams are
426 not guaranteed to be sent and received in discrete packets. (But small
427 datagrams around 500 bytes that are not truncated by `process-send-string'
428 are usually fine.) Note further that UDP protocol does not guard against
429 lost packets."
430 (open-network-stream-internal name buffer host service protocol))
431 317
432 (defun shell-quote-argument (argument) 318 (defun shell-quote-argument (argument)
433 "Quote an argument for passing as argument to an inferior shell." 319 "Quote an argument for passing as argument to an inferior shell."
434 (if (and (eq system-type 'windows-nt) 320 (if (eq system-type 'ms-dos)
435 ;; #### this is a temporary hack. a better solution needs 321 ;; MS-DOS shells don't have quoting, so don't do any.
436 ;; futzing with the c code. i'll do this shortly.
437 (let ((progname (downcase (file-name-nondirectory
438 shell-file-name))))
439 (or (equal progname "command.com")
440 (equal progname "cmd.exe"))))
441 argument 322 argument
442 ;; Quote everything except POSIX filename characters. 323 (if (eq system-type 'windows-nt)
443 ;; This should be safe enough even for really weird shells. 324 (concat "\"" argument "\"")
444 (let ((result "") (start 0) end) 325 ;; Quote everything except POSIX filename characters.
445 (while (string-match "[^-0-9a-zA-Z_./]" argument start) 326 ;; This should be safe enough even for really weird shells.
446 (setq end (match-beginning 0) 327 (let ((result "") (start 0) end)
447 result (concat result (substring argument start end) 328 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
448 "\\" (substring argument end (1+ end))) 329 (setq end (match-beginning 0)
449 start (1+ end))) 330 result (concat result (substring argument start end)
450 (concat result (substring argument start))))) 331 "\\" (substring argument end (1+ end)))
451 332 start (1+ end)))
452 (defun shell-command-to-string (command) 333 (concat result (substring argument start))))))
453 "Execute shell command COMMAND and return its output as a string." 334
335 (defun exec-to-string (command)
336 "Execute COMMAND as an external process and return the output of that
337 process as a string"
338 ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu>
454 (with-output-to-string 339 (with-output-to-string
455 (call-process shell-file-name nil t nil shell-command-switch command))) 340 (call-process shell-file-name nil t nil shell-command-switch command)))
456 341
457 (defalias 'exec-to-string 'shell-command-to-string) 342 (defalias 'shell-command-to-string 'exec-to-string)
458 343
459 ;;; process.el ends here 344 ;;; process.el ends here