diff options
author | John Wiegley <johnw@newartisans.com> | 2000-08-29 00:47:45 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2000-08-29 00:47:45 +0000 |
commit | 34e176b0d7977b82397380392f2770e0fabb17b2 (patch) | |
tree | 72aea13a30ebdb17b749765aad97bda2d1fca720 /lisp/eshell/esh-proc.el | |
parent | bc46ba862fbb0432ce12570606fdc35d9e3f021c (diff) | |
download | emacs-34e176b0d7977b82397380392f2770e0fabb17b2.tar.gz |
See ChangeLog
Diffstat (limited to 'lisp/eshell/esh-proc.el')
-rw-r--r-- | lisp/eshell/esh-proc.el | 137 |
1 files changed, 97 insertions, 40 deletions
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index ead49e1942f..ddb2c986a96 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -125,14 +125,15 @@ information, for example." "Reset the command input location after a process terminates. The signals which will cause this to happen are matched by `eshell-reset-signals'." - (if (string-match eshell-reset-signals status) + (if (and (stringp status) + (string-match eshell-reset-signals status)) (eshell-reset))) (defun eshell-wait-for-process (&rest procs) "Wait until PROC has successfully completed." (while procs (let ((proc (car procs))) - (when (processp proc) + (when (eshell-processp proc) ;; NYI: If the process gets stopped here, that's bad. (while (assq proc eshell-process-list) (if (input-pending-p) @@ -145,7 +146,8 @@ The signals which will cause this to happen are matched by (defun eshell/jobs (&rest args) "List processes, if there are any." - (and (process-list) + (and (fboundp 'process-list) + (process-list) (list-processes))) (defun eshell/kill (&rest args) @@ -153,7 +155,7 @@ The signals which will cause this to happen are matched by (let ((ptr args) (signum 'SIGINT)) (while ptr - (if (or (processp (car ptr)) + (if (or (eshell-processp (car ptr)) (and (stringp (car ptr)) (string-match "^[A-Za-z/][A-Za-z0-9<>/]+$" (car ptr)))) @@ -162,7 +164,7 @@ The signals which will cause this to happen are matched by (setcar ptr (get-process (car ptr)))) (setq ptr (cdr ptr))) (while args - (let ((id (if (processp (car args)) + (let ((id (if (eshell-processp (car args)) (process-id (car args)) (car args)))) (when id @@ -206,7 +208,7 @@ The prompt will be set to PROMPT." (defsubst eshell-record-process-object (object) "Record OBJECT as now running." - (if (and (processp object) + (if (and (eshell-processp object) eshell-current-subjob-p) (eshell-interactive-print (format "[%s] %d\n" (process-name object) (process-id object)))) @@ -217,7 +219,7 @@ The prompt will be set to PROMPT." (defun eshell-remove-process-entry (entry) "Record the process ENTRY as fully completed." - (if (and (processp (car entry)) + (if (and (eshell-processp (car entry)) (nth 2 entry) eshell-done-messages-in-minibuffer) (message (format "[%s]+ Done %s" (process-name (car entry)) @@ -225,6 +227,12 @@ The prompt will be set to PROMPT." (setq eshell-process-list (delq entry eshell-process-list))) +(defvar eshell-scratch-buffer " *eshell-scratch*" + "Scratch buffer for holding Eshell's input/output.") +(defvar eshell-last-sync-output-start nil + "A marker that tracks the beginning of output of the last subprocess. +Used only on systems which do not support async subprocesses.") + (defun eshell-gather-process-output (command args) "Gather the output from COMMAND + ARGS." (unless (and (file-executable-p command) @@ -235,39 +243,88 @@ The prompt will be set to PROMPT." eshell-delete-exited-processes delete-exited-processes)) (process-environment (eshell-environment-variables)) - (proc (apply 'start-process - (file-name-nondirectory command) nil - ;; `start-process' can't deal with relative - ;; filenames - (append (list (expand-file-name command)) args))) - decoding encoding changed) - (eshell-record-process-object proc) - (set-process-buffer proc (current-buffer)) - (if (eshell-interactive-output-p) - (set-process-filter proc 'eshell-output-filter) - (set-process-filter proc 'eshell-insertion-filter)) - (set-process-sentinel proc 'eshell-sentinel) - (run-hook-with-args 'eshell-exec-hook proc) - (when (fboundp 'process-coding-system) - (let ((coding-systems (process-coding-system proc))) - (setq decoding (car coding-systems) - encoding (cdr coding-systems))) - ;; If start-process decided to use some coding system for - ;; decoding data sent from the process and the coding system - ;; doesn't specify EOL conversion, we had better convert CRLF - ;; to LF. - (if (vectorp (coding-system-eol-type decoding)) - (setq decoding (coding-system-change-eol-conversion decoding 'dos) - changed t)) - ;; Even if start-process left the coding system for encoding - ;; data sent from the process undecided, we had better use the - ;; same one as what we use for decoding. But, we should - ;; suppress EOL conversion. - (if (and decoding (not encoding)) - (setq encoding (coding-system-change-eol-conversion decoding 'unix) - changed t)) - (if changed - (set-process-coding-system proc decoding encoding))) + proc decoding encoding changed) + (cond + ((fboundp 'start-process) + (setq proc + (apply 'start-process + (file-name-nondirectory command) nil + ;; `start-process' can't deal with relative + ;; filenames + (append (list (expand-file-name command)) args))) + (eshell-record-process-object proc) + (set-process-buffer proc (current-buffer)) + (if (eshell-interactive-output-p) + (set-process-filter proc 'eshell-output-filter) + (set-process-filter proc 'eshell-insertion-filter)) + (set-process-sentinel proc 'eshell-sentinel) + (run-hook-with-args 'eshell-exec-hook proc) + (when (fboundp 'process-coding-system) + (let ((coding-systems (process-coding-system proc))) + (setq decoding (car coding-systems) + encoding (cdr coding-systems))) + ;; If start-process decided to use some coding system for + ;; decoding data sent from the process and the coding system + ;; doesn't specify EOL conversion, we had better convert CRLF + ;; to LF. + (if (vectorp (coding-system-eol-type decoding)) + (setq decoding (coding-system-change-eol-conversion decoding 'dos) + changed t)) + ;; Even if start-process left the coding system for encoding + ;; data sent from the process undecided, we had better use the + ;; same one as what we use for decoding. But, we should + ;; suppress EOL conversion. + (if (and decoding (not encoding)) + (setq encoding (coding-system-change-eol-conversion decoding 'unix) + changed t)) + (if changed + (set-process-coding-system proc decoding encoding)))) + (t + ;; No async subprocesses... + (let ((oldbuf (current-buffer)) + (interact-p (eshell-interactive-output-p)) + lbeg lend line proc-buf exit-status) + (and (not (markerp eshell-last-sync-output-start)) + (setq eshell-last-sync-output-start (point-marker))) + (setq proc-buf + (set-buffer (get-buffer-create eshell-scratch-buffer))) + (erase-buffer) + (set-buffer oldbuf) + (run-hook-with-args 'eshell-exec-hook command) + (setq exit-status + (apply 'call-process-region + (append (list eshell-last-sync-output-start (point) + command t + eshell-scratch-buffer nil) + args))) + ;; When in a pipeline, record the place where the output of + ;; this process will begin. + (and eshell-in-pipeline-p + (set-marker eshell-last-sync-output-start (point))) + ;; Simulate the effect of the process filter. + (when (numberp exit-status) + (set-buffer proc-buf) + (goto-char (point-min)) + (setq lbeg (point)) + (while (eq 0 (forward-line 1)) + (setq lend (point) + line (buffer-substring-no-properties lbeg lend)) + (set-buffer oldbuf) + (if interact-p + (eshell-output-filter nil line) + (eshell-output-object line)) + (setq lbeg lend) + (set-buffer proc-buf)) + (set-buffer oldbuf)) + (eshell-update-markers eshell-last-output-end) + ;; Simulate the effect of eshell-sentinel. + (eshell-close-handles (if (numberp exit-status) exit-status -1)) + (run-hook-with-args 'eshell-kill-hook command exit-status) + (or eshell-in-pipeline-p + (setq eshell-last-sync-output-start nil)) + (if (not (numberp exit-status)) + (error "%s: external command failed: %s" command exit-status)) + (setq proc t)))) proc)) (defun eshell-insertion-filter (proc string) |