]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement Tramp direct async processes fallback for multi-hops
authorMichael Albinus <michael.albinus@gmx.de>
Wed, 12 Aug 2020 10:45:45 +0000 (12:45 +0200)
committerMichael Albinus <michael.albinus@gmx.de>
Wed, 12 Aug 2020 10:45:45 +0000 (12:45 +0200)
* doc/misc/tramp.texi (Remote processes): Precise restrictions for direct
async processes.

* lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
* lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
Use `tramp-direct-async-process-p'.

* lisp/net/tramp.el (tramp-direct-async-process-p): New defun.
(tramp-handle-make-process): Adapt handling of :stderr.  Simplify.

doc/misc/tramp.texi
lisp/net/tramp-adb.el
lisp/net/tramp-sh.el
lisp/net/tramp.el

index 23221b6a7b8d08510b2950aa880b82d460f5087a..c1a66d0251212ef95d706b4ee86dae8947b2bb3b 100644 (file)
@@ -3561,23 +3561,23 @@ which must be set to a non-@code{nil} value.  Example:
 @end group
 @end lisp
 
-However, this approach has different limitations:
+Using direct asynchronous processes in @value{tramp} is not possible,
+if the remote host is connected via multiple hops
+(@pxref{Multi-hops}), or the @code{make-process} /
+@code{start-file-process} call uses a stderr stream.  In this case,
+@value{tramp} falls back to its classical implementation.
+
+Furthermore, this approach has the following limitations:
 
 @itemize
 @item
 It works only for connection methods defined in @file{tramp-sh.el} and
 @file{tramp-adb.el}.
 
-@item
-It does not support multi-hop methods.
-
 @item
 It does not support interactive user authentication, like password
 handling.
 
-@item
-It does not support a separated error stream.
-
 @item
 It cannot be killed via @code{interrupt-process}.
 
@@ -3594,7 +3594,10 @@ It does not set environment variable @env{INSIDE_EMACS}.
 
 In order to gain even more performance, it is recommended to bind
 @code{tramp-verbose} to 0 when running @code{make-process} or
-@code{start-file-process}.
+@code{start-file-process}.  Furthermore, you might set
+@code{tramp-use-ssh-controlmaster-options} to @code{nil} in order to
+bypass @value{tramp}'s handling of the @code{ControlMaster} options,
+and use your own settings in @file{~/.ssh/config}.
 
 
 @node Cleanup remote connections
index 88f5c2928e3cf1830ebc5f40a7d0ded4558d37d0..49ecaa58ee8c91c0f8064367c9a3c6f2a764a428 100644 (file)
@@ -890,8 +890,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
   "Like `make-process' for Tramp files.
 If connection property \"direct-async-process\" is non-nil, an
 alternative implementation will be used."
-  (if (tramp-get-connection-property
-       (tramp-dissect-file-name default-directory) "direct-async-process" nil)
+  (if (tramp-direct-async-process-p args)
       (apply #'tramp-handle-make-process args)
     (when args
       (with-parsed-tramp-file-name (expand-file-name default-directory) nil
index 3e2eb023a33b34cc0c1b7cfb8535e5af13ed4c45..ca43475f4532d6c296c4a3afd48420df40eecb8a 100644 (file)
@@ -2790,8 +2790,7 @@ the result will be a local, non-Tramp, file name."
 STDERR can also be a file name.  If connection property
 \"direct-async-process\" is non-nil, an alternative
 implementation will be used."
-  (if (tramp-get-connection-property
-       (tramp-dissect-file-name default-directory) "direct-async-process" nil)
+  (if (tramp-direct-async-process-p args)
       (apply #'tramp-handle-make-process args)
     (when args
       (with-parsed-tramp-file-name (expand-file-name default-directory) nil
index d8113a9af9bb1b83ef37f8761453b8b45c536318..ab52bec39eb57b6f22a85e5c87fe72ad807101fa 100644 (file)
@@ -3633,18 +3633,29 @@ User is always nil."
                (load local-copy noerror t nosuffix must-suffix)
              (delete-file local-copy)))))
       t)))
+
+(defun tramp-direct-async-process-p (&rest args)
+  "Whether direct async `make-process' can be called."
+  (let ((v (tramp-dissect-file-name default-directory)))
+    (and (tramp-get-connection-property v"direct-async-process" nil)
+          (not (tramp-multi-hop-p v))
+          (not (plist-get args :stderr)))))
+
 ;; We use BUFFER also as connection buffer during setup. Because of
 ;; this, its original contents must be saved, and restored once
 ;; connection has been setup.
 (defun tramp-handle-make-process (&rest args)
-  "An alternative `make-process' implementation for Tramp files."
+  "An alternative `make-process' implementation for Tramp files.
+It does not support `:stderr'."
   (when args
     (with-parsed-tramp-file-name (expand-file-name default-directory) nil
       (let ((name (plist-get args :name))
            (buffer (plist-get args :buffer))
            (command (plist-get args :command))
+           ;; FIXME: `:coding' shall be used.
            (coding (plist-get args :coding))
            (noquery (plist-get args :noquery))
+           ;; FIXME: `:connection-type' shall be used.
            (connection-type (plist-get args :connection-type))
            (filter (plist-get args :filter))
            (sentinel (plist-get args :sentinel))
@@ -3667,11 +3678,12 @@ User is always nil."
          (signal 'wrong-type-argument (list #'functionp filter)))
        (unless (or (null sentinel) (functionp sentinel))
          (signal 'wrong-type-argument (list #'functionp sentinel)))
-       (unless (or (null stderr) (bufferp stderr) (stringp stderr))
-         (signal 'wrong-type-argument (list #'stringp stderr)))
-       (when (and (stringp stderr) (tramp-tramp-file-p stderr)
-                  (not (tramp-equal-remote default-directory stderr)))
-         (signal 'file-error (list "Wrong stderr" stderr)))
+       (when stderr
+         (signal
+          'user-error
+          (list
+           "Stderr not supported for direct remote asynchronous processes"
+           stderr)))
 
        (let* ((buffer
                (if buffer
@@ -3698,9 +3710,12 @@ User is always nil."
          (tramp-set-connection-property v "process-name" name)
          (tramp-set-connection-property v "process-buffer" buffer)
 
+         ;; Check for `tramp-sh-file-name-handler', because something
+         ;; is different between tramp-adb.el and tramp-sh.el.
          (with-current-buffer (tramp-get-connection-buffer v)
            (unwind-protect
-               (let* ((login-program
+               (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v))
+                      (login-program
                        (tramp-get-method-parameter v 'tramp-login-program))
                       (login-args
                        (tramp-get-method-parameter v 'tramp-login-args))
@@ -3716,12 +3731,12 @@ User is always nil."
                       ;; in the main connection process, therefore
                       ;; we cannot use `tramp-get-connection-process'.
                       (tmpfile
-                       (when (tramp-sh-file-name-handler-p v)
+                       (when sh-file-name-handler-p
                          (with-tramp-connection-property
                              (tramp-get-process v) "temp-file"
                            (tramp-compat-make-temp-name))))
                       (options
-                       (when (tramp-sh-file-name-handler-p v)
+                       (when sh-file-name-handler-p
                          (tramp-compat-funcall
                           'tramp-ssh-controlmaster-options v)))
                       spec)