]> code.delx.au - gnu-emacs/blobdiff - lisp/eshell/esh-proc.el
Fix previous rmail-output-read-file-name change
[gnu-emacs] / lisp / eshell / esh-proc.el
index 25d9dd6466390512c3d78a27b9a519b5b53d5c01..f510f4b5329beabfd9d872ebaf746d21bf2c369f 100644 (file)
@@ -1,7 +1,6 @@
 ;;; esh-proc.el --- process management
 
 ;;; 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 <johnw@gnu.org>
 
 
 ;; Author: John Wiegley <johnw@gnu.org>
 
@@ -22,6 +21,8 @@
 
 ;;; Commentary:
 
 
 ;;; Commentary:
 
+;;; Code:
+
 (provide 'esh-proc)
 
 (eval-when-compile
 (provide 'esh-proc)
 
 (eval-when-compile
@@ -37,28 +38,29 @@ finish."
 
 ;;; User Variables:
 
 
 ;;; 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
   :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
   :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
   :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
   :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.
 
 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\\)"
 
 (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
   :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').
 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)
 
   :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."
 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)
 
   :type 'hook
   :group 'eshell-proc)
 
@@ -112,6 +115,14 @@ information, for example."
 
 ;;; Functions:
 
 
 ;;; 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)
 (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.")
 
   "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)
 (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
     (error "%s: not an executable file" command))
   (let* ((delete-exited-processes
          (if eshell-current-subjob-p
@@ -248,13 +279,16 @@ Used only on systems which do not support async subprocesses.")
         (process-environment (eshell-environment-variables))
         proc decoding encoding changed)
     (cond
         (process-environment (eshell-environment-variables))
         proc decoding encoding changed)
     (cond
-     ((fboundp 'start-process)
+     ((fboundp 'start-file-process)
       (setq proc
       (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)))
+           (let ((process-connection-type
+                  (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.
+                    (append (list (expand-file-name command)) args))))
       (eshell-record-process-object proc)
       (set-process-buffer proc (current-buffer))
       (if (eshell-interactive-output-p)
       (eshell-record-process-object proc)
       (set-process-buffer proc (current-buffer))
       (if (eshell-interactive-output-p)
@@ -322,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))
        (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))
        (or eshell-in-pipeline-p
            (setq eshell-last-sync-output-start nil))
        (if (not (numberp exit-status))
@@ -367,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))))
                      (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)
 
 (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
       (if (and (memq (process-status (car entry))
                    '(run stop open closed))
               (or all
@@ -388,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.
     ;; 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
       (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)
   :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
 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
@@ -407,7 +441,7 @@ tries the next signal in the list."
   :group 'eshell-proc)
 
 (defcustom eshell-kill-processes-on-exit nil
   :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
 Emacs will only kill processes owned by that Eshell buffer.
 
 If nil, ownership of background and foreground processes reverts to
@@ -461,31 +495,29 @@ See the variable `eshell-kill-processes-on-exit'."
            (kill-buffer buf)))
       (message nil))))
 
            (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)
 (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)
 
 (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)
 
 (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)
 
 ;(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."
 
 ;(defun eshell-continue-process ()
 ;  "Send CONTINUE signal to process."
@@ -494,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'.
 ;    ;; 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."
 
 (defun eshell-send-eof-to-process ()
   "Send EOF to process."
@@ -502,7 +534,4 @@ See the variable `eshell-kill-processes-on-exit'."
   (eshell-send-input nil nil t)
   (eshell-process-interact 'process-send-eof))
 
   (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
 ;;; esh-proc.el ends here