From c9d06d080bb2bd012813d6e5ac1f3deb32ccb29f Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 17 Jan 2022 10:46:58 +0100 Subject: [PATCH] Improve handling of INFILE in tramp*-process-file (Bug#53284) * lisp/net/tramp-adb.el (tramp-adb-handle-process-file): * lisp/net/tramp-sh.el (tramp-sh-handle-process-file): * lisp/net/tramp-smb.el (tramp-smb-handle-process-file): * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file): Improve handling of INFILE. Fix thinko using `process-file-side-effects'. (Bug#53284) * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist): Use `tramp-sshfs-handle-set-file-times'. (tramp-sshfs-handle-set-file-times): New defun. * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Extend test. --- lisp/net/tramp-adb.el | 8 ++++---- lisp/net/tramp-sh.el | 8 ++++---- lisp/net/tramp-smb.el | 5 ++--- lisp/net/tramp-sshfs.el | 38 +++++++++++++++++++++++++++++++----- test/lisp/net/tramp-tests.el | 14 ++++++++++++- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index ed73a86ef03..699dec4d58e 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -815,7 +815,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; Determine input. (if (null infile) (setq input (tramp-get-remote-null-device v)) - (setq infile (expand-file-name infile)) + (setq infile (tramp-compat-file-name-unquote (expand-file-name infile))) (if (tramp-equal-remote default-directory infile) ;; INFILE is on the same remote host. (setq input (tramp-file-local-name infile)) @@ -870,7 +870,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setq ret (tramp-adb-send-command-and-check v (format "(cd %s; %s)" - (tramp-shell-quote-argument localname) command) + (tramp-unquote-shell-quote-argument localname) + command) t)) (unless (natnump ret) (setq ret 1)) ;; We should add the output anyway. @@ -900,8 +901,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; Cleanup. We remove all file cache values for the connection, ;; because the remote process could have changed them. (when tmpinput (delete-file tmpinput)) - - (unless process-file-side-effects + (when process-file-side-effects (tramp-flush-directory-properties v "")) ;; Return exit status. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 72b1ebb3e06..ffa11b1fe3c 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -3098,7 +3098,7 @@ implementation will be used." ;; Determine input. (if (null infile) (setq input (tramp-get-remote-null-device v)) - (setq infile (expand-file-name infile)) + (setq infile (tramp-compat-file-name-unquote (expand-file-name infile))) (if (tramp-equal-remote default-directory infile) ;; INFILE is on the same remote host. (setq input (tramp-file-local-name infile)) @@ -3153,7 +3153,8 @@ implementation will be used." (setq ret (tramp-send-command-and-check v (format "cd %s && %s" - (tramp-shell-quote-argument localname) command) + (tramp-unquote-shell-quote-argument localname) + command) t t t)) (unless (natnump ret) (setq ret 1)) ;; We should add the output anyway. @@ -3184,8 +3185,7 @@ implementation will be used." ;; Cleanup. We remove all file cache values for the connection, ;; because the remote process could have changed them. (when tmpinput (delete-file tmpinput)) - - (unless process-file-side-effects + (when process-file-side-effects (tramp-flush-directory-properties v "")) ;; Return exit status. diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index c5f423fa3f0..6515519680c 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1281,7 +1281,7 @@ component is used as the target of the symlink." ;; Determine input. (when infile - (setq infile (expand-file-name infile)) + (setq infile (tramp-compat-file-name-unquote (expand-file-name infile))) (if (tramp-equal-remote default-directory infile) ;; INFILE is on the same remote host. (setq input (tramp-file-local-name infile)) @@ -1373,8 +1373,7 @@ component is used as the target of the symlink." (when tmpinput (delete-file tmpinput)) (unless outbuf (kill-buffer (tramp-get-connection-property v "process-buffer" nil))) - - (unless process-file-side-effects + (when process-file-side-effects (tramp-flush-directory-properties v "")) ;; Return exit status. diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index 0a5bf2f43b3..8890d0ec5c3 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -137,7 +137,7 @@ (set-file-acl . ignore) (set-file-modes . tramp-sshfs-handle-set-file-modes) (set-file-selinux-context . ignore) - (set-file-times . ignore) + (set-file-times . tramp-sshfs-handle-set-file-times) (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) (shell-command . tramp-handle-shell-command) (start-file-process . tramp-handle-start-file-process) @@ -242,13 +242,28 @@ arguments to pass to the OPERATION." (let ((command (format "cd %s && exec %s" - localname - (mapconcat #'tramp-shell-quote-argument (cons program args) " ")))) + (tramp-unquote-shell-quote-argument localname) + (mapconcat #'tramp-shell-quote-argument (cons program args) " "))) + input tmpinput) + + ;; Determine input. + (if (null infile) + (setq input (tramp-get-remote-null-device v)) + (setq infile (tramp-compat-file-name-unquote (expand-file-name infile))) + (if (tramp-equal-remote default-directory infile) + ;; INFILE is on the same remote host. + (setq input (tramp-file-local-name infile)) + ;; INFILE must be copied to remote host. + (setq input (tramp-make-tramp-temp-file v) + tmpinput (tramp-make-tramp-file-name v input 'nohop)) + (copy-file infile tmpinput t))) + (when input (setq command (format "%s <%s" command input))) + (unwind-protect (apply #'tramp-call-process v (tramp-get-method-parameter v 'tramp-login-program) - infile destination display + nil destination display (tramp-expand-args v 'tramp-login-args ?h (or (tramp-file-name-host v) "") @@ -256,7 +271,11 @@ arguments to pass to the OPERATION." ?p (or (tramp-file-name-port v) "") ?l command)) - (unless process-file-side-effects + ;; Cleanup. We remove all file cache values for the + ;; connection, because the remote process could have changed + ;; them. + (when tmpinput (delete-file tmpinput)) + (when process-file-side-effects (tramp-flush-directory-properties v "")))))) (defun tramp-sshfs-handle-rename-file @@ -285,6 +304,15 @@ arguments to pass to the OPERATION." (tramp-compat-set-file-modes (tramp-fuse-local-file-name filename) mode flag)))) +(defun tramp-sshfs-handle-set-file-times (filename &optional timestamp flag) + "Like `set-file-times' for Tramp files." + (or (file-exists-p filename) (write-region "" nil filename nil 0)) + (with-parsed-tramp-file-name filename nil + (unless (and (eq flag 'nofollow) (file-symlink-p filename)) + (tramp-flush-file-properties v localname) + (tramp-compat-set-file-times + (tramp-fuse-local-file-name filename) timestamp flag)))) + (defun tramp-sshfs-handle-write-region (start end filename &optional append visit lockname mustbenew) "Like `write-region' for Tramp files." diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index ea0ff3c760e..a07d749916e 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4504,7 +4504,19 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (should (string-equal (format "%s\n%s\n" fnnd fnnd) (buffer-string))) ;; A non-nil DISPLAY must not raise the buffer. - (should-not (get-buffer-window (current-buffer) t)))) + (should-not (get-buffer-window (current-buffer) t)) + (delete-file tmp-name)) + + ;; Check remote and local INFILE. + (dolist (local '(nil t)) + (with-temp-buffer + (setq tmp-name (tramp--test-make-temp-name local quoted)) + (write-region "foo" nil tmp-name) + (should (file-exists-p tmp-name)) + (should (zerop (process-file "cat" tmp-name t))) + (should (string-equal "foo" (buffer-string))) + (should-not (get-buffer-window (current-buffer) t))) + (delete-file tmp-name))) ;; Cleanup. (ignore-errors (delete-file tmp-name)))))) -- 2.39.2