X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/403e4dc9896abde019ebb48c0303de5c9e1c44e6..7cef3569a3d872ea5be07a529b68910bf1d8b790:/lisp/eshell/esh-proc.el diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 39fea83cd8..f510f4b532 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -1,7 +1,6 @@ ;;; esh-proc.el --- process management -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, -;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +;; Copyright (C) 1999-2012 Free Software Foundation, Inc. ;; Author: John Wiegley @@ -22,6 +21,8 @@ ;;; Commentary: +;;; Code: + (provide 'esh-proc) (eval-when-compile @@ -37,28 +38,29 @@ finish." ;;; User Variables: -(defcustom eshell-proc-load-hook '(eshell-proc-initialize) - "*A hook that gets run when `eshell-proc' is loaded." +(defcustom eshell-proc-load-hook nil + "A hook that gets run when `eshell-proc' is loaded." + :version "24.1" ; removed eshell-proc-initialize :type 'hook :group 'eshell-proc) (defcustom eshell-process-wait-seconds 0 - "*The number of seconds to delay waiting for a synchronous process." + "The number of seconds to delay waiting for a synchronous process." :type 'integer :group 'eshell-proc) (defcustom eshell-process-wait-milliseconds 50 - "*The number of milliseconds to delay waiting for a synchronous process." + "The number of milliseconds to delay waiting for a synchronous process." :type 'integer :group 'eshell-proc) (defcustom eshell-done-messages-in-minibuffer t - "*If non-nil, subjob \"Done\" messages will display in minibuffer." + "If non-nil, subjob \"Done\" messages will display in minibuffer." :type 'boolean :group 'eshell-proc) (defcustom eshell-delete-exited-processes t - "*If nil, process entries will stick around until `jobs' is run. + "If nil, process entries will stick around until `jobs' is run. This variable sets the buffer-local value of `delete-exited-processes' in Eshell buffers. @@ -79,12 +81,12 @@ variable's value to take effect." (defcustom eshell-reset-signals "^\\(interrupt\\|killed\\|quit\\|stopped\\)" - "*If a termination signal matches this regexp, the terminal will be reset." + "If a termination signal matches this regexp, the terminal will be reset." :type 'regexp :group 'eshell-proc) (defcustom eshell-exec-hook nil - "*Called each time a process is exec'd by `eshell-gather-process-output'. + "Called each time a process is exec'd by `eshell-gather-process-output'. It is passed one argument, which is the process that was just started. It is useful for things that must be done each time a process is executed in a eshell mode buffer (e.g., `process-kill-without-query'). @@ -93,13 +95,14 @@ is created." :type 'hook :group 'eshell-proc) -(defcustom eshell-kill-hook '(eshell-reset-after-proc) - "*Called when a process run by `eshell-gather-process-output' has ended. +(defcustom eshell-kill-hook nil + "Called when a process run by `eshell-gather-process-output' has ended. It is passed two arguments: the process that was just ended, and the termination status (as a string). Note that the first argument may be nil, in which case the user attempted to send a signal, but there was no relevant process. This can be used for displaying help information, for example." + :version "24.1" ; removed eshell-reset-after-proc :type 'hook :group 'eshell-proc) @@ -112,6 +115,14 @@ information, for example." ;;; Functions: +(defun eshell-kill-process-function (proc status) + "Function run when killing a process. +Runs `eshell-reset-after-proc' and `eshell-kill-hook', passing arguments +PROC and STATUS to both." + (or (memq 'eshell-reset-after-proc eshell-kill-hook) + (eshell-reset-after-proc proc status)) + (run-hook-with-args 'eshell-kill-hook proc status)) + (defun eshell-proc-initialize () "Initialize the process handling code." (make-local-variable 'eshell-process-list) @@ -236,10 +247,30 @@ The prompt will be set to PROMPT." "A marker that tracks the beginning of output of the last subprocess. Used only on systems which do not support async subprocesses.") +(defvar eshell-needs-pipe '("bc") + "List of commands which need `process-connection-type' to be nil. +Currently only affects commands in pipelines, and not those at +the front. If an element contains a directory part it must match +the full name of a command, otherwise just the nondirectory part must match.") + +(defun eshell-needs-pipe-p (command) + "Return non-nil if COMMAND needs `process-connection-type' to be nil. +See `eshell-needs-pipe'." + (and eshell-in-pipeline-p + (not (eq eshell-in-pipeline-p 'first)) + ;; FIXME should this return non-nil for anything that is + ;; neither 'first nor 'last? See bug#1388 discussion. + (catch 'found + (dolist (exe eshell-needs-pipe) + (if (string-equal exe (if (string-match "/" exe) + command + (file-name-nondirectory command))) + (throw 'found t)))))) + (defun eshell-gather-process-output (command args) "Gather the output from COMMAND + ARGS." (unless (and (file-executable-p command) - (file-regular-p command)) + (file-regular-p (file-truename command))) (error "%s: not an executable file" command)) (let* ((delete-exited-processes (if eshell-current-subjob-p @@ -248,28 +279,15 @@ Used only on systems which do not support async subprocesses.") (process-environment (eshell-environment-variables)) proc decoding encoding changed) (cond - ((fboundp 'start-process) + ((fboundp 'start-file-process) (setq proc - ;; Bug#1388. Some commands (eg bc) check isatty to decide - ;; whether they are being called interactively. - ;; A normal shell pipeline has: - ;; first: stdin tty , stdout pipe - ;; rest : stdin pipe, stdout pipe - ;; last : stdin pipe, stdout tty - ;; We have: - ;; first: stdin tty , stdout tty - ;; last : stdin pipe, stdout pipe - ;; In other words, the first and last elements have the - ;; wrong kind of stdout. (Perhaps this does not matter much...) - ;; FIXME which is better for the first element: - ;; tty/tty (as now), or pipe/pipe? (let ((process-connection-type - (unless (and eshell-in-pipeline-p - (not (eq eshell-in-pipeline-p 'first))) - process-connection-type))) - (apply 'start-process + (unless (eshell-needs-pipe-p command) + process-connection-type)) + (command (or (file-remote-p command 'localname) command))) + (apply 'start-file-process (file-name-nondirectory command) nil - ;; `start-process' can't deal with relative filenames + ;; `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)) @@ -338,7 +356,7 @@ Used only on systems which do not support async subprocesses.") (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) + (eshell-kill-process-function command exit-status) (or eshell-in-pipeline-p (setq eshell-last-sync-output-start nil)) (if (not (numberp exit-status)) @@ -383,14 +401,14 @@ PROC is the process that's exiting. STRING is the exit message." (eshell-close-handles (process-exit-status proc) 'nil (cadr entry)))) (eshell-remove-process-entry entry)))) - (run-hook-with-args 'eshell-kill-hook proc string))))) + (eshell-kill-process-function proc string))))) (defun eshell-process-interact (func &optional all query) "Interact with a process, using PROMPT if more than one, via FUNC. If ALL is non-nil, background processes will be interacted with as well. If QUERY is non-nil, query the user with QUERY before calling FUNC." (let (defunct result) - (eshell-for entry eshell-process-list + (dolist (entry eshell-process-list) (if (and (memq (process-status (car entry)) '(run stop open closed)) (or all @@ -404,17 +422,17 @@ If QUERY is non-nil, query the user with QUERY before calling FUNC." ;; clean up the process list; this can get dirty if an error ;; occurred that brought the user into the debugger, and then they ;; quit, so that the sentinel was never called. - (eshell-for d defunct + (dolist (d defunct) (eshell-remove-process-entry d)) result)) (defcustom eshell-kill-process-wait-time 5 - "*Seconds to wait between sending termination signals to a subprocess." + "Seconds to wait between sending termination signals to a subprocess." :type 'integer :group 'eshell-proc) (defcustom eshell-kill-process-signals '(SIGINT SIGQUIT SIGKILL) - "*Signals used to kill processes when an Eshell buffer exits. + "Signals used to kill processes when an Eshell buffer exits. Eshell calls each of these signals in order when an Eshell buffer is killed; if the process is still alive afterwards, Eshell waits a number of seconds defined by `eshell-kill-process-wait-time', and @@ -423,7 +441,7 @@ tries the next signal in the list." :group 'eshell-proc) (defcustom eshell-kill-processes-on-exit nil - "*If non-nil, kill active processes when exiting an Eshell buffer. + "If non-nil, kill active processes when exiting an Eshell buffer. Emacs will only kill processes owned by that Eshell buffer. If nil, ownership of background and foreground processes reverts to @@ -477,31 +495,29 @@ See the variable `eshell-kill-processes-on-exit'." (kill-buffer buf))) (message nil)))) -(custom-add-option 'eshell-exit-hook 'eshell-query-kill-processes) - (defun eshell-interrupt-process () "Interrupt a process." (interactive) (unless (eshell-process-interact 'interrupt-process) - (run-hook-with-args 'eshell-kill-hook nil "interrupt"))) + (eshell-kill-process-function nil "interrupt"))) (defun eshell-kill-process () "Kill a process." (interactive) (unless (eshell-process-interact 'kill-process) - (run-hook-with-args 'eshell-kill-hook nil "killed"))) + (eshell-kill-process-function nil "killed"))) (defun eshell-quit-process () "Send quit signal to process." (interactive) (unless (eshell-process-interact 'quit-process) - (run-hook-with-args 'eshell-kill-hook nil "quit"))) + (eshell-kill-process-function nil "quit"))) ;(defun eshell-stop-process () ; "Send STOP signal to process." ; (interactive) ; (unless (eshell-process-interact 'stop-process) -; (run-hook-with-args 'eshell-kill-hook nil "stopped"))) +; (eshell-kill-process-function nil "stopped"))) ;(defun eshell-continue-process () ; "Send CONTINUE signal to process." @@ -510,7 +526,7 @@ See the variable `eshell-kill-processes-on-exit'." ; ;; jww (1999-09-17): this signal is not dealt with yet. For ; ;; example, `eshell-reset' will be called, and so will ; ;; `eshell-resume-eval'. -; (run-hook-with-args 'eshell-kill-hook nil "continue"))) +; (eshell-kill-process-function nil "continue"))) (defun eshell-send-eof-to-process () "Send EOF to process." @@ -518,7 +534,4 @@ See the variable `eshell-kill-processes-on-exit'." (eshell-send-input nil nil t) (eshell-process-interact 'process-send-eof)) -;;; Code: - -;; arch-tag: ac477a3e-ee4d-4b44-8ec6-212010e607bb ;;; esh-proc.el ends here