;; 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
(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)
"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."
(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"
(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.
(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)))
(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)