From: Michael Albinus Date: Fri, 22 Dec 2023 18:58:32 +0000 (+0100) Subject: Tramp's direct asynchronous processes use 'tramp-remote-path' X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=9c86dd52475e0ad65359bc964fbe0d62b9d3e464;p=emacs.git Tramp's direct asynchronous processes use 'tramp-remote-path' * doc/misc/tramp.texi (Remote processes): Remove item about tramp-remote-path. * etc/NEWS: Direct asynchronous processes use 'tramp-remote-path'. * lisp/net/tramp-sh.el (tramp-get-remote-pipe-buf): New defun. (tramp-set-remote-path): Use it. (tramp-get-remote-path): Add ;;;###tramp-autoload cookie. * lisp/net/tramp.el (tramp-handle-make-process): Use `tramp-remote-path' for setting PATH environment. * test/lisp/net/tramp-tests.el (tramp-test35-exec-path-direct-async) (tramp-test35-remote-path-direct-async): New tests. --- diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 7a95a6dbc98..4eeb75b664d 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -4406,9 +4406,6 @@ It does not report the remote terminal name via @code{process-tty-name}. @item It does not set process property @code{remote-pid}. - -@item -It does not use @code{tramp-remote-path}. @end itemize In order to gain even more performance, it is recommended to bind diff --git a/etc/NEWS b/etc/NEWS index b39dd5f5ab6..03218d08d80 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -78,7 +78,7 @@ removed, as it was considered more dangerous than useful. RFC 9110 'url-personal-mail-address' is now also obsolete. To send an email address in the header of individual HTTP requests, -see the variable `url-request-extra-headers'. +see the variable 'url-request-extra-headers'. * Changes in Emacs 30.1 @@ -809,6 +809,11 @@ buffer must either visit a file, or it must run 'dired-mode'. Another method but "sudo" can be configured with user option 'tramp-file-name-with-method'. +--- +*** Direct asynchronous processes use 'tramp-remote-path'. +When a direct asynchronous process is invoked, it uses 'tramp-remote-path' +for setting the remote PATH environment variable. + ** File Notifications +++ diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index a7ead1f2997..064045584ae 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4175,18 +4175,6 @@ This function expects to be in the right *tramp* buffer." ;; On hydra.nixos.org, the $PATH environment variable is too long to ;; send it. This is likely not due to PATH_MAX, but PIPE_BUF. We ;; check it, and use a temporary file in case of. See Bug#33781. - -;; The PIPE_BUF in POSIX [1] can be as low as 512 [2]. Here are the values -;; on various platforms: -;; - 512 on macOS, FreeBSD, NetBSD, OpenBSD, MirBSD, native Windows. -;; - 4 KiB on Linux, OSF/1, Cygwin, Haiku. -;; - 5 KiB on Solaris. -;; - 8 KiB on HP-UX, Plan9. -;; - 10 KiB on IRIX. -;; - 32 KiB on AIX, Minix. -;; [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html -;; [2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html -;; See Bug#65324. (defun tramp-set-remote-path (vec) "Set the remote environment PATH to existing directories. I.e., for each directory in `tramp-remote-path', it is tested @@ -4196,13 +4184,7 @@ variable PATH." (format "PATH=%s && export PATH" (string-join (tramp-get-remote-path vec) ":"))) - (pipe-buf - (with-tramp-connection-property vec "pipe-buf" - (tramp-send-command-and-read - vec - (format "getconf PIPE_BUF / 2>%s || echo 4096" - (tramp-get-remote-null-device vec)) - 'noerror))) + (pipe-buf (tramp-get-remote-pipe-buf vec)) tmpfile chunk chunksize) (tramp-message vec 5 "Setting $PATH environment variable") (if (tramp-compat-length< command pipe-buf) @@ -5597,6 +5579,7 @@ raises an error." "Check whether REGEXP matches the connection property \"uname\"." (string-match-p regexp (tramp-get-connection-property vec "uname" ""))) +;;;###tramp-autoload (defun tramp-get-remote-path (vec) "Compile list of remote directories for PATH. Nonexistent directories are removed from spec." @@ -5680,6 +5663,27 @@ Nonexistent directories are removed from spec." (lambda (x) (not (tramp-get-file-property vec x "file-directory-p"))) remote-path)))))) +;; The PIPE_BUF in POSIX [1] can be as low as 512 [2]. Here are the values +;; on various platforms: +;; - 512 on macOS, FreeBSD, NetBSD, OpenBSD, MirBSD, native Windows. +;; - 4 KiB on Linux, OSF/1, Cygwin, Haiku. +;; - 5 KiB on Solaris. +;; - 8 KiB on HP-UX, Plan9. +;; - 10 KiB on IRIX. +;; - 32 KiB on AIX, Minix. +;; [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html +;; [2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html +;; See Bug#65324. +;;;###tramp-autoload +(defun tramp-get-remote-pipe-buf (vec) + "Return PIPE_BUF config from the remote side." + (with-tramp-connection-property vec "pipe-buf" + (tramp-send-command-and-read + vec + (format "getconf PIPE_BUF / 2>%s || echo 4096" + (tramp-get-remote-null-device vec)) + 'noerror))) + (defun tramp-get-remote-locale (vec) "Determine remote locale, supporting UTF8 if possible." (with-tramp-connection-property vec "locale" diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 88cbfa2d88c..0207805c720 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4849,7 +4849,12 @@ a connection-local variable." (unless (or (null stderr) (bufferp stderr)) (signal 'wrong-type-argument (list #'bufferp stderr))) - (let* ((buffer + ;; Check for `tramp-sh-file-name-handler', because something + ;; is different between tramp-sh.el, and tramp-adb.el or + ;; tramp-sshfs.el. + (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v)) + (adb-file-name-handler-p (tramp-adb-file-name-p v)) + (buffer (if buffer (get-buffer-create buffer) ;; BUFFER can be nil. We use a temporary buffer. @@ -4869,6 +4874,12 @@ a connection-local variable." (member elt (default-toplevel-value 'process-environment)))) (setq env (cons elt env))))) + ;; Add remote path if exists. + (env (if-let ((sh-file-name-handler-p) + (remote-path + (string-join (tramp-get-remote-path v) ":"))) + (setenv-internal env "PATH" remote-path 'keep) + env)) (env (setenv-internal env "INSIDE_EMACS" (tramp-inside-emacs) 'keep)) (env (mapcar #'tramp-shell-quote-argument (delq nil env))) @@ -4879,83 +4890,83 @@ a connection-local variable." (append `("cd" ,(tramp-shell-quote-argument localname) "&&" "(" "env") env `(,command ")"))) - ;; Add remote shell if needed. + ;; Add remote shell if needed. (command (if (consp (tramp-get-method-parameter v 'tramp-direct-async)) (append (tramp-get-method-parameter v 'tramp-direct-async) `(,(string-join command " "))) - command))) - - ;; Check for `tramp-sh-file-name-handler', because something - ;; is different between tramp-sh.el, and tramp-adb.el or - ;; tramp-sshfs.el. - (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v)) - (adb-file-name-handler-p (tramp-adb-file-name-p v)) - (login-program - (tramp-get-method-parameter v 'tramp-login-program)) - ;; We don't create the temporary file. In fact, it - ;; is just a prefix for the ControlPath option of - ;; ssh; the real temporary file has another name, and - ;; it is created and protected by ssh. It is also - ;; removed by ssh when the connection is closed. The - ;; temporary file name is cached in the main - ;; connection process, therefore we cannot use - ;; `tramp-get-connection-process'. - (tmpfile - (when sh-file-name-handler-p - (with-tramp-connection-property - (tramp-get-process v) "temp-file" - (tramp-compat-make-temp-name)))) - (options - (when sh-file-name-handler-p - (tramp-compat-funcall - 'tramp-ssh-controlmaster-options v))) - (device - (when adb-file-name-handler-p - (tramp-compat-funcall - 'tramp-adb-get-device v))) - (pta (unless (eq connection-type 'pipe) "-t")) - login-args p) - - ;; Replace `login-args' place holders. Split - ;; ControlMaster options. - (setq - login-args - (append - (flatten-tree (tramp-get-method-parameter v 'tramp-async-args)) - (flatten-tree - (mapcar - (lambda (x) (split-string x " ")) - (tramp-expand-args - v 'tramp-login-args - ?h (or host "") ?u (or user "") ?p (or port "") - ?c (format-spec (or options "") (format-spec-make ?t tmpfile)) - ?d (or device "") ?a (or pta "") ?l "")))) - p (make-process - :name name :buffer buffer - :command (append `(,login-program) login-args command) - :coding coding :noquery noquery :connection-type connection-type - :sentinel sentinel :stderr stderr)) - ;; Set filter. Prior Emacs 29.1, it doesn't work reliably - ;; to provide it as `make-process' argument when filter is - ;; t. See Bug#51177. - (when filter - (set-process-filter p filter)) - (tramp-post-process-creation p v) - ;; Query flag is overwritten in `tramp-post-process-creation', - ;; so we reset it. - (set-process-query-on-exit-flag p (null noquery)) - ;; This is needed for ssh or PuTTY based processes, and - ;; only if the respective options are set. Perhaps, the - ;; setting could be more fine-grained. - ;; (process-put p 'tramp-shared-socket t) - (process-put p 'remote-command orig-command) - (tramp-set-connection-property p "remote-command" orig-command) - (when (bufferp stderr) - (tramp-taint-remote-process-buffer stderr)) - - p)))))) + command)) + (login-program + (tramp-get-method-parameter v 'tramp-login-program)) + ;; We don't create the temporary file. In fact, it is + ;; just a prefix for the ControlPath option of ssh; the + ;; real temporary file has another name, and it is + ;; created and protected by ssh. It is also removed by + ;; ssh when the connection is closed. The temporary + ;; file name is cached in the main connection process, + ;; therefore we cannot use + ;; `tramp-get-connection-process'. + (tmpfile + (when sh-file-name-handler-p + (with-tramp-connection-property + (tramp-get-process v) "temp-file" + (tramp-compat-make-temp-name)))) + (options + (when sh-file-name-handler-p + (tramp-compat-funcall + 'tramp-ssh-controlmaster-options v))) + (device + (when adb-file-name-handler-p + (tramp-compat-funcall + 'tramp-adb-get-device v))) + (pta (unless (eq connection-type 'pipe) "-t")) + login-args p) + + ;; Command could be too long, for example due to a longish PATH. + (when (and sh-file-name-handler-p + (tramp-compat-length> + (string-join command) (tramp-get-remote-pipe-buf v))) + (signal 'error (cons "Command too long:" command))) + + ;; Replace `login-args' place holders. Split ControlMaster + ;; options. + (setq + login-args + (append + (flatten-tree (tramp-get-method-parameter v 'tramp-async-args)) + (flatten-tree + (mapcar + (lambda (x) (split-string x " ")) + (tramp-expand-args + v 'tramp-login-args + ?h (or host "") ?u (or user "") ?p (or port "") + ?c (format-spec (or options "") (format-spec-make ?t tmpfile)) + ?d (or device "") ?a (or pta "") ?l "")))) + p (make-process + :name name :buffer buffer + :command (append `(,login-program) login-args command) + :coding coding :noquery noquery :connection-type connection-type + :sentinel sentinel :stderr stderr)) + ;; Set filter. Prior Emacs 29.1, it doesn't work reliably + ;; to provide it as `make-process' argument when filter is + ;; t. See Bug#51177. + (when filter + (set-process-filter p filter)) + (tramp-post-process-creation p v) + ;; Query flag is overwritten in `tramp-post-process-creation', + ;; so we reset it. + (set-process-query-on-exit-flag p (null noquery)) + ;; This is needed for ssh or PuTTY based processes, and + ;; only if the respective options are set. Perhaps, the + ;; setting could be more fine-grained. + ;; (process-put p 'tramp-shared-socket t) + (process-put p 'remote-command orig-command) + (tramp-set-connection-property p "remote-command" orig-command) + (when (bufferp stderr) + (tramp-taint-remote-process-buffer stderr)) + + p))))) (defun tramp-handle-make-symbolic-link (_target linkname &optional _ok-if-already-exists) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 68bf928eb62..209eb1a055c 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6347,6 +6347,8 @@ INPUT, if non-nil, is a string sent to the process." ;; Cleanup. (ignore-errors (delete-file tmp-name))))) +(tramp--test-deftest-direct-async-process tramp-test35-exec-path) + ;; This test is inspired by Bug#33781. (ert-deftest tramp-test35-remote-path () "Check loooong `tramp-remote-path'." @@ -6411,6 +6413,8 @@ INPUT, if non-nil, is a string sent to the process." (setq tramp-remote-path orig-tramp-remote-path) (ignore-errors (delete-directory tmp-name 'recursive))))) +(tramp--test-deftest-direct-async-process tramp-test35-remote-path) + (ert-deftest tramp-test36-vc-registered () "Check `vc-registered'." :tags '(:expensive-test)