diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el index b7089207..08f7a04d 100644 --- a/lisp/tramp-sh.el +++ b/lisp/tramp-sh.el @@ -1361,32 +1361,34 @@ component is used as the target of the symlink." (tramp-message vec 5 "file attributes with stat: %s" localname) (tramp-send-command-and-read vec - (format - (eval-when-compile - (concat - ;; On Opsware, pdksh (which is the true name of ksh there) - ;; doesn't parse correctly the sequence "((". Therefore, we - ;; add a space. Apostrophes in the stat output are masked as - ;; `tramp-stat-marker', in order to make a proper shell escape - ;; of them in file names. - "( (%s %s || %s -h %s) && (%s -c " - "'((%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' " - "%s | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g') || echo nil)")) - (tramp-get-file-exists-command vec) - (tramp-shell-quote-argument localname) - (tramp-get-test-command vec) - (tramp-shell-quote-argument localname) - (tramp-get-remote-stat vec) - tramp-stat-marker tramp-stat-marker - (if (eq id-format 'integer) - "%u" - (eval-when-compile (concat tramp-stat-marker "%U" tramp-stat-marker))) - (if (eq id-format 'integer) - "%g" - (eval-when-compile (concat tramp-stat-marker "%G" tramp-stat-marker))) - tramp-stat-marker tramp-stat-marker - (tramp-shell-quote-argument localname) - tramp-stat-quoted-marker))) + (tramp-shorten-long-command + vec + (format + (eval-when-compile + (concat + ;; On Opsware, pdksh (which is the true name of ksh there) + ;; doesn't parse correctly the sequence "((". Therefore, we + ;; add a space. Apostrophes in the stat output are masked as + ;; `tramp-stat-marker', in order to make a proper shell escape + ;; of them in file names. + "( (%s %s || %s -h %s) && (%s -c " + "'((%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' " + "%s | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g') || echo nil)")) + (tramp-get-file-exists-command vec) + (tramp-shell-quote-argument localname) + (tramp-get-test-command vec) + (tramp-shell-quote-argument localname) + (tramp-get-remote-stat vec) + tramp-stat-marker tramp-stat-marker + (if (eq id-format 'integer) + "%u" + (eval-when-compile (concat tramp-stat-marker "%U" tramp-stat-marker))) + (if (eq id-format 'integer) + "%g" + (eval-when-compile (concat tramp-stat-marker "%G" tramp-stat-marker))) + tramp-stat-marker tramp-stat-marker + (tramp-shell-quote-argument localname) + tramp-stat-quoted-marker)))) (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." @@ -3956,25 +3958,13 @@ This function expects to be in the right *tramp* buffer." I.e., for each directory in `tramp-remote-path', it is tested whether it exists and if so, it is added to the environment variable PATH." - (let ((command - (format - "PATH=%s; export PATH" (string-join (tramp-get-remote-path vec) ":"))) - (pipe-buf - (or (with-tramp-connection-property vec "pipe-buf" - (tramp-send-command-and-read - vec "getconf PIPE_BUF / 2>/dev/null || echo nil" 'noerror)) - 4096)) - tmpfile) (tramp-message vec 5 "Setting $PATH environment variable") - (if (< (length command) pipe-buf) - (tramp-send-command vec command) - ;; Use a temporary file. - (setq tmpfile - (tramp-make-tramp-file-name vec (tramp-make-tramp-temp-file vec))) - (write-region command nil tmpfile) - (tramp-send-command - vec (format ". %s" (tramp-compat-file-local-name tmpfile))) - (delete-file tmpfile)))) + (tramp-send-command + vec + (tramp-shorten-long-command + vec + (format + "PATH=%s; export PATH" (string-join (tramp-get-remote-path vec) ":"))))) ;; ------------------------------------------------------------ ;; -- Communication with external shell -- @@ -5043,6 +5033,30 @@ connection if a previous connection has died for some reason." (tramp-cleanup-connection vec t) (signal (car err) (cdr err)))))) +(defun tramp-shorten-long-command (vec command) + "Return the command to be used. +If COMMAND is too long, write it to a temporary file, and return +a command to source that temporary file." + (if (< (length command) + ;; PIPE_BUF is undefined on Solaris. But there's a report of + ;; a problem with a command longer than 256 characters. + (or (with-tramp-connection-property + (tramp-get-connection-process vec) "pipe-buf" + (tramp-send-command-and-read + vec "getconf PIPE_BUF / 2>/dev/null || echo nil" 'noerror)) + 256)) + command + ;; Use a temporary file. We must exclude `tramp-get-remote-stat' + ;; in order to avoid an infinite loop. + (cl-letf (((symbol-function 'tramp-get-remote-stat) 'ignore)) + (let ((tmpfile + (tramp-make-tramp-file-name vec (tramp-make-tramp-temp-file vec)))) + (write-region command nil tmpfile) + (tramp-message vec 6 "%s" command) + (format ". %s && rm -f %s" + (tramp-compat-file-local-name tmpfile) + (tramp-compat-file-local-name tmpfile)))))) + (defun tramp-send-command (vec command &optional neveropen nooutput) "Send the COMMAND to connection VEC. Erases temporary buffer before sending the command. If optional