diff options
Diffstat (limited to 'lisp/net')
-rw-r--r-- | lisp/net/tramp-adb.el | 36 | ||||
-rw-r--r-- | lisp/net/tramp-archive.el | 10 | ||||
-rw-r--r-- | lisp/net/tramp-cache.el | 2 | ||||
-rw-r--r-- | lisp/net/tramp-crypt.el | 8 | ||||
-rw-r--r-- | lisp/net/tramp-gvfs.el | 46 | ||||
-rw-r--r-- | lisp/net/tramp-rclone.el | 10 | ||||
-rw-r--r-- | lisp/net/tramp-sh.el | 43 | ||||
-rw-r--r-- | lisp/net/tramp-smb.el | 11 | ||||
-rw-r--r-- | lisp/net/tramp-sshfs.el | 134 | ||||
-rw-r--r-- | lisp/net/tramp-sudoedit.el | 11 | ||||
-rw-r--r-- | lisp/net/trampver.el | 6 |
11 files changed, 226 insertions, 91 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 3c1b032baf6..aa0f558a2b6 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -815,10 +815,10 @@ 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)) + (setq input (tramp-unquote-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)) @@ -849,7 +849,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setcar (cdr destination) (expand-file-name (cadr destination))) (if (tramp-equal-remote default-directory (cadr destination)) ;; stderr is on the same remote host. - (setq stderr (tramp-file-local-name (cadr destination))) + (setq stderr (tramp-unquote-file-local-name (cadr destination))) ;; stderr must be copied to remote host. The temporary ;; file must be deleted after execution. (setq stderr (tramp-make-tramp-temp-file v) @@ -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. @@ -986,6 +986,10 @@ implementation will be used." (name1 name) (i 0)) + (when (string-match-p "[[:multibyte:]]" command) + (tramp-error + v 'file-error "Cannot apply multi-byte command `%s'" command)) + (while (get-process name1) ;; NAME must be unique as process name. (setq i (1+ i) @@ -1264,7 +1268,7 @@ connection if a previous connection has died for some reason." (if (zerop (length device)) (tramp-error vec 'file-error "Device %s not connected" host)) (with-tramp-progress-reporter vec 3 "Opening adb shell connection" - (let* ((coding-system-for-read 'utf-8-dos) ;is this correct? + (let* ((coding-system-for-read 'utf-8-dos) ; Is this correct? (process-connection-type tramp-process-connection-type) (args (if (> (length host) 0) (list "-s" device "shell") @@ -1368,6 +1372,24 @@ connection if a previous connection has died for some reason." `(:application tramp :protocol ,tramp-adb-method) 'tramp-adb-connection-local-default-shell-profile)) +;; `shell-mode' tries to open remote files like "/adb::~/.history". +;; This fails, because the tilde cannot be expanded. Tell +;; `tramp-handle-expand-file-name' to tolerate this. +(defun tramp-adb-tolerate-tilde (orig-fun) + "Advice for `shell-mode' to tolerate tilde in remote file names." + (let ((tramp-tolerate-tilde + (or tramp-tolerate-tilde + (equal (file-remote-p default-directory 'method) + tramp-adb-method)))) + (funcall orig-fun))) + +(add-function + :around (symbol-function #'shell-mode) #'tramp-adb-tolerate-tilde) +(add-hook 'tramp-adb-unload-hook + (lambda () + (remove-function + (symbol-function #'shell-mode) #'tramp-adb-tolerate-tilde))) + (add-hook 'tramp-unload-hook (lambda () (unload-feature 'tramp-adb 'force))) diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index 1b5f42a9912..22390ef45bc 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el @@ -188,6 +188,8 @@ It must be supported by libarchive(3).") "\\)" ;; \1 "\\(" "/" ".*" "\\)" "\\'"))) ;; \2 +(put #'tramp-archive-autoload-file-name-regexp 'tramp-autoload t) + ;; In older Emacsen (prior 27.1), `tramp-archive-autoload-file-name-regexp' ;; is not autoloaded. So we cannot expect it to be known in ;; tramp-loaddefs.el. But it exists, when tramp-archive.el is loaded. @@ -363,15 +365,21 @@ arguments to pass to the OPERATION." (tramp-archive-autoload t)) (apply #'tramp-autoload-file-name-handler operation args))))) +(put #'tramp-archive-autoload-file-name-handler 'tramp-autoload t) + ;;;###autoload (progn (defun tramp-register-archive-file-name-handler () "Add archive file name handler to `file-name-handler-alist'." - (when tramp-archive-enabled + (when (and tramp-archive-enabled + (not + (rassq #'tramp-archive-file-name-handler file-name-handler-alist))) (add-to-list 'file-name-handler-alist (cons (tramp-archive-autoload-file-name-regexp) #'tramp-archive-autoload-file-name-handler)) (put #'tramp-archive-autoload-file-name-handler 'safe-magic t)))) +(put #'tramp-register-archive-file-name-handler 'tramp-autoload t) + ;;;###autoload (progn (add-hook 'after-init-hook #'tramp-register-archive-file-name-handler) diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index d35f7ffa4e3..347da916edf 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -49,8 +49,6 @@ ;; an open connection. Examples: "scripts" keeps shell script ;; definitions already sent to the remote shell, "last-cmd-time" is ;; the time stamp a command has been sent to the remote process. -;; "lock-pid" is the timestamp a (network) process is created, it is -;; used instead of the pid in file locks. ;; ;; - The key is nil. These are temporary properties related to the ;; local machine. Examples: "parse-passwd" and "parse-group" keep diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index e8313463da4..5028e489328 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el @@ -192,9 +192,9 @@ If NAME doesn't belong to a crypted remote directory, retun nil." ;; `file-name-nondirectory' performed by default handler. ;; `file-name-sans-versions' performed by default handler. (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-notify-add-watch . ignore) - (file-notify-rm-watch . ignore) - (file-notify-valid-p . ignore) + (file-notify-add-watch . tramp-handle-file-notify-add-watch) + (file-notify-rm-watch . tramp-handle-file-notify-rm-watch) + (file-notify-valid-p . tramp-handle-file-notify-valid-p) (file-ownership-preserved-p . tramp-crypt-handle-file-ownership-preserved-p) (file-readable-p . tramp-crypt-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) @@ -207,7 +207,7 @@ If NAME doesn't belong to a crypted remote directory, retun nil." (find-backup-file-name . tramp-handle-find-backup-file-name) ;; `get-file-buffer' performed by default handler. (insert-directory . tramp-crypt-handle-insert-directory) - ;; `insert-file-contents' performed by default handler. + (insert-file-contents . tramp-handle-insert-file-contents) (load . tramp-handle-load) (lock-file . tramp-crypt-handle-lock-file) (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 0bba894cdbb..c09c016e647 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -1160,10 +1160,9 @@ file names." (tramp-get-connection-property v "default-location" "~") nil t localname 1))) ;; Tilde expansion is not possible. - (when (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname) - (tramp-error - v 'file-error - "Cannot expand tilde in file `%s'" name)) + (when (and (not tramp-tolerate-tilde) + (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)) + (tramp-error v 'file-error "Cannot expand tilde in file `%s'" name)) (unless (tramp-run-real-handler #'file-name-absolute-p (list localname)) (setq localname (concat "/" localname))) ;; We do not pass "/..". @@ -1181,7 +1180,9 @@ file names." ;; No tilde characters in file name, do normal ;; `expand-file-name' (this does "/./" and "/../"). (tramp-make-tramp-file-name - v (tramp-run-real-handler #'expand-file-name (list localname)))))) + v (if (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname) + localname + (tramp-run-real-handler #'expand-file-name (list localname))))))) (defun tramp-gvfs-get-directory-attributes (directory) "Return GVFS attributes association list of all files in DIRECTORY." @@ -1396,7 +1397,8 @@ If FILE-SYSTEM is non-nil, return file system attributes." "Like `file-executable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-tramp-file-property v localname "file-executable-p" - (tramp-check-cached-permissions v ?x)))) + (or (tramp-check-cached-permissions v ?x) + (tramp-check-cached-permissions v ?s))))) (defun tramp-gvfs-handle-file-name-all-completions (filename directory) "Like `file-name-all-completions' for Tramp files." @@ -1612,22 +1614,18 @@ ID-FORMAT valid values are `string' and `integer'." (tramp-file-name-user vec) (when-let ((localname (tramp-get-connection-property - (tramp-get-process vec) "share" - (tramp-get-connection-property vec "default-location" nil)))) + (tramp-get-process vec) "share" nil))) (tramp-compat-file-attribute-user-id - (file-attributes - (tramp-make-tramp-file-name vec localname) id-format))))) + (file-attributes (tramp-make-tramp-file-name vec localname) id-format))))) (defun tramp-gvfs-handle-get-remote-gid (vec id-format) "The gid of the remote connection VEC, in ID-FORMAT. ID-FORMAT valid values are `string' and `integer'." (when-let ((localname (tramp-get-connection-property - (tramp-get-process vec) "share" - (tramp-get-connection-property vec "default-location" nil)))) + (tramp-get-process vec) "share" nil))) (tramp-compat-file-attribute-group-id - (file-attributes - (tramp-make-tramp-file-name vec localname) id-format)))) + (file-attributes (tramp-make-tramp-file-name vec localname) id-format)))) (defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid) "Like `tramp-set-file-uid-gid' for Tramp files." @@ -2134,9 +2132,6 @@ connection if a previous connection has died for some reason." (process-put p 'vector vec) (set-process-query-on-exit-flag p nil) - ;; Mark process for filelock. - (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds))) - ;; Set connection-local variables. (tramp-set-connection-local-variables vec))) @@ -2256,13 +2251,7 @@ connection if a previous connection has died for some reason." COMMAND is a command from the gvfs-* utilities. It is replaced by the corresponding gio tool call if available. `call-process' is applied, and it returns t if the return code is zero." - (let* ((locale (tramp-get-local-locale vec)) - (process-environment - (append - `(,(format "LANG=%s" locale) - ,(format "LANGUAGE=%s" locale) - ,(format "LC_ALL=%s" locale)) - process-environment))) + (let ((locale (tramp-get-local-locale vec))) (when (tramp-gvfs-gio-tool-p vec) ;; Use gio tool. (setq args (cons (cdr (assoc command tramp-gvfs-gio-mapping)) @@ -2272,7 +2261,14 @@ is applied, and it returns t if the return code is zero." (with-current-buffer (tramp-get-connection-buffer vec) (tramp-gvfs-maybe-open-connection vec) (erase-buffer) - (or (zerop (apply #'tramp-call-process vec command nil t nil args)) + (or (zerop + (apply + #'tramp-call-process vec "env" nil t nil + (append `(,(format "LANG=%s" locale) + ,(format "LANGUAGE=%s" locale) + ,(format "LC_ALL=%s" locale) + ,command) + args))) ;; Remove information about mounted connection. (and (tramp-flush-file-properties vec "/") nil))))) diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 20e983c77d1..318df2de615 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -106,9 +106,9 @@ (file-name-nondirectory . tramp-handle-file-name-nondirectory) ;; `file-name-sans-versions' performed by default handler. (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-notify-add-watch . ignore) - (file-notify-rm-watch . ignore) - (file-notify-valid-p . ignore) + (file-notify-add-watch . tramp-handle-file-notify-add-watch) + (file-notify-rm-watch . tramp-handle-file-notify-rm-watch) + (file-notify-valid-p . tramp-handle-file-notify-valid-p) (file-ownership-preserved-p . ignore) (file-readable-p . tramp-fuse-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) @@ -362,10 +362,6 @@ connection if a previous connection has died for some reason." (process-put p 'vector vec) (set-process-query-on-exit-flag p nil) - ;; Mark process for filelock. - (tramp-set-connection-property - p "lock-pid" (truncate (time-to-seconds))) - ;; Set connection-local variables. (tramp-set-connection-local-variables vec))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index de4d579740a..54fb539a564 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1574,6 +1574,7 @@ ID-FORMAT valid values are `string' and `integer'." ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. (or (tramp-check-cached-permissions v ?x) + (tramp-check-cached-permissions v ?s) (tramp-run-test "-x" filename))))) (defun tramp-sh-handle-file-readable-p (filename) @@ -2663,7 +2664,9 @@ The method used must be an out-of-band method." ;; Try to insert the amount of free space. (goto-char (point-min)) ;; First find the line to put it on. - (when (re-search-forward "^\\([[:space:]]*total\\)" nil t) + (when (and (re-search-forward "^\\([[:space:]]*total\\)" nil t) + ;; Emacs 29.1 or later. + (not (fboundp 'dired--insert-disk-space))) (when-let ((available (get-free-disk-space "."))) ;; Replace "total" with "total used", to avoid confusion. (replace-match "\\1 used in directory") @@ -2817,8 +2820,10 @@ implementation will be used." (string-match-p "sh$" program) (= (length args) 2) (string-equal "-c" (car args)) - ;; Don't if there is a string. - (not (string-match-p "'\\|\"" (cadr args))))) + ;; Don't if there is a quoted string. + (not (string-match-p "'\\|\"" (cadr args))) + ;; Check, that /dev/tty is usable. + (tramp-get-remote-dev-tty v))) ;; When PROGRAM is nil, we just provide a tty. (args (if (not heredoc) args (let ((i 250)) @@ -3080,10 +3085,10 @@ 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)) + (setq input (tramp-unquote-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)) @@ -3114,7 +3119,7 @@ implementation will be used." (setcar (cdr destination) (expand-file-name (cadr destination))) (if (tramp-equal-remote default-directory (cadr destination)) ;; stderr is on the same remote host. - (setq stderr (tramp-file-local-name (cadr destination))) + (setq stderr (tramp-unquote-file-local-name (cadr destination))) ;; stderr must be copied to remote host. The temporary ;; file must be deleted after execution. (setq stderr (tramp-make-tramp-temp-file v) @@ -3135,7 +3140,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. @@ -3167,8 +3173,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. @@ -4093,13 +4098,10 @@ file exists and nonzero exit status otherwise." ;; The algorithm is as follows: we try a list of several commands. ;; For each command, we first run `$cmd /' -- this should return ;; true, as the root directory always exists. And then we run - ;; `$cmd /this\ file\ does\ not\ exist ', hoping that the file indeed - ;; does not exist. This should return false. We use the first - ;; command we find that seems to work. + ;; `$cmd /\ this\ file\ does\ not\ exist\ ', hoping that the file + ;; indeed does not exist. This should return false. We use the + ;; first command we find that seems to work. ;; The list of commands to try is as follows: - ;; `ls -d' This works on most systems, but NetBSD 1.4 - ;; has a bug: `ls' always returns zero exit - ;; status, even for files which don't exist. ;; `test -e' Some Bourne shells have a `test' builtin ;; which does not know the `-e' option. ;; `/bin/test -e' For those, the `test' binary on disk normally @@ -4107,6 +4109,10 @@ file exists and nonzero exit status otherwise." ;; is sometimes `/bin/test' and sometimes it's ;; `/usr/bin/test'. ;; `/usr/bin/test -e' In case `/bin/test' does not exist. + ;; `ls -d' This works on most systems, but NetBSD 1.4 + ;; has a bug: `ls' always returns zero exit + ;; status, even for files which don't exist. + (unless (or (ignore-errors (and (setq result (format "%s -e" (tramp-get-test-command vec))) @@ -4839,6 +4845,7 @@ connection if a previous connection has died for some reason." ;; If Tramp opens the same connection within a short time frame, ;; there is a problem. We shall signal this. (unless (or (process-live-p p) + (and (processp p) (not non-essential)) (not (tramp-file-name-equal-p vec (car tramp-current-connection))) (time-less-p @@ -5815,6 +5822,12 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil." command)) (delete-file tmpfile))))) +(defun tramp-get-remote-dev-tty (vec) + "Check, whether remote /dev/tty is usable." + (with-tramp-connection-property vec "dev-tty" + (tramp-send-command-and-check + vec "echo </dev/tty"))) + ;; Some predefined connection properties. (defun tramp-get-inline-compress (vec prop size) "Return the compress command related to PROP. diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 3960554605d..2aaa6e8ab3f 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1126,7 +1126,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; Insert size information. (when full-directory-p (insert - (if avail + (if (and avail + ;; Emacs 29.1 or later. + (not (fboundp 'dired--insert-disk-space))) (format "total used in directory %s available %s\n" used avail) (format "total %s\n" used)))) @@ -1284,10 +1286,10 @@ 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)) + (setq input (tramp-unquote-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)) @@ -1376,8 +1378,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 7be26bd23df..b229f589248 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -51,11 +51,14 @@ (add-to-list 'tramp-methods `(,tramp-sshfs-method (tramp-mount-args (("-C") ("-p" "%p") + ("-o" "dir_cache=no") + ("-o" "transform_symlinks") ("-o" "idmap=user,reconnect"))) ;; These are for remote processes. (tramp-login-program "ssh") - (tramp-login-args (("-q")("-l" "%u") ("-p" "%p") - ("-e" "none") ("%h") ("%l"))) + (tramp-login-args (("-q") ("-l" "%u") ("-p" "%p") + ("-e" "none") ("-t" "-t") + ("%h") ("%l"))) (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) @@ -106,9 +109,9 @@ (file-name-nondirectory . tramp-handle-file-name-nondirectory) ;; `file-name-sans-versions' performed by default handler. (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-notify-add-watch . ignore) - (file-notify-rm-watch . ignore) - (file-notify-valid-p . ignore) + (file-notify-add-watch . tramp-handle-file-notify-add-watch) + (file-notify-rm-watch . tramp-handle-file-notify-rm-watch) + (file-notify-valid-p . tramp-handle-file-notify-valid-p) (file-ownership-preserved-p . ignore) (file-readable-p . tramp-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) @@ -117,7 +120,7 @@ (file-symlink-p . tramp-handle-file-symlink-p) (file-system-info . tramp-sshfs-handle-file-system-info) (file-truename . tramp-handle-file-truename) - (file-writable-p . tramp-handle-file-writable-p) + (file-writable-p . tramp-sshfs-handle-file-writable-p) (find-backup-file-name . tramp-handle-find-backup-file-name) ;; `get-file-buffer' performed by default handler. (insert-directory . tramp-handle-insert-directory) @@ -136,7 +139,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) @@ -219,6 +222,10 @@ arguments to pass to the OPERATION." ;;`file-system-info' exists since Emacs 27.1. (tramp-compat-funcall 'file-system-info (tramp-fuse-local-file-name filename))) +(defun tramp-sshfs-handle-file-writable-p (filename) + "Like `file-writable-p' for Tramp files." + (file-writable-p (tramp-fuse-local-file-name filename))) + (defun tramp-sshfs-handle-insert-file-contents (filename &optional visit beg end replace) "Like `insert-file-contents' for Tramp files." @@ -239,16 +246,69 @@ arguments to pass to the OPERATION." (error "Implementation does not handle immediate return")) (with-parsed-tramp-file-name (expand-file-name default-directory) nil - (let ((command + (let ((coding-system-for-read 'utf-8-dos) ; Is this correct? + (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 stderr tmpstderr outbuf) + + ;; 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-unquote-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))) + + ;; Determine output. + (cond + ;; Just a buffer. + ((bufferp destination) + (setq outbuf destination)) + ;; A buffer name. + ((stringp destination) + (setq outbuf (get-buffer-create destination))) + ;; (REAL-DESTINATION ERROR-DESTINATION) + ((consp destination) + ;; output. + (cond + ((bufferp (car destination)) + (setq outbuf (car destination))) + ((stringp (car destination)) + (setq outbuf (get-buffer-create (car destination)))) + ((car destination) + (setq outbuf (current-buffer)))) + ;; stderr. + (cond + ((stringp (cadr destination)) + (setcar (cdr destination) (expand-file-name (cadr destination))) + (if (tramp-equal-remote default-directory (cadr destination)) + ;; stderr is on the same remote host. + (setq stderr (tramp-unquote-file-local-name (cadr destination))) + ;; stderr must be copied to remote host. The temporary + ;; file must be deleted after execution. + (setq stderr (tramp-make-tramp-temp-file v) + tmpstderr (tramp-make-tramp-file-name v stderr)))) + ;; stderr to be discarded. + ((null (cadr destination)) + (setq stderr (tramp-get-remote-null-device v))))) + ;; 't + (destination + (setq outbuf (current-buffer)))) + (when stderr (setq command (format "%s 2>%s" command stderr))) + (unwind-protect (apply #'tramp-call-process v (tramp-get-method-parameter v 'tramp-login-program) - infile destination display + nil outbuf display (tramp-expand-args v 'tramp-login-args ?h (or (tramp-file-name-host v) "") @@ -256,7 +316,20 @@ arguments to pass to the OPERATION." ?p (or (tramp-file-name-port v) "") ?l command)) - (unless process-file-side-effects + ;; Synchronize stderr. + (when tmpstderr + (tramp-cleanup-connection v 'keep-debug 'keep-password) + (tramp-fuse-unmount v)) + + ;; Provide error file. + (when tmpstderr + (rename-file tmpstderr (cadr destination) t)) + + ;; 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 +358,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." @@ -313,6 +395,13 @@ arguments to pass to the OPERATION." start end (tramp-fuse-local-file-name filename) append 'nomessage) (tramp-flush-file-properties v localname)) + ;; Set file modification time. + (when (or (eq visit t) (stringp visit)) + (set-visited-file-modtime + (or (tramp-compat-file-attribute-modification-time + (file-attributes filename)) + (current-time)))) + ;; Unlock file. (when file-locked ;; `unlock-file' exists since Emacs 28.1. @@ -345,9 +434,6 @@ connection if a previous connection has died for some reason." (process-put p 'vector vec) (set-process-query-on-exit-flag p nil) - ;; Mark process for filelock. - (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds))) - ;; Set connection-local variables. (tramp-set-connection-local-variables vec))) @@ -386,6 +472,24 @@ connection if a previous connection has died for some reason." (with-tramp-connection-property vec "gid-string" (tramp-get-local-gid 'string))) +;; `shell-mode' tries to open remote files like "/sshfs:user@host:~/.history". +;; This fails, because the tilde cannot be expanded. Tell +;; `tramp-handle-expand-file-name' to tolerate this. +(defun tramp-sshfs-tolerate-tilde (orig-fun) + "Advice for `shell-mode' to tolerate tilde in remote file names." + (let ((tramp-tolerate-tilde + (or tramp-tolerate-tilde + (equal (file-remote-p default-directory 'method) + tramp-sshfs-method)))) + (funcall orig-fun))) + +(add-function + :around (symbol-function #'shell-mode) #'tramp-sshfs-tolerate-tilde) +(add-hook 'tramp-sshfs-unload-hook + (lambda () + (remove-function + (symbol-function #'shell-mode) #'tramp-sshfs-tolerate-tilde))) + (add-hook 'tramp-unload-hook (lambda () (unload-feature 'tramp-sshfs 'force))) diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index c4222b28a20..06100fbde0d 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -99,9 +99,9 @@ See `tramp-actions-before-shell' for more info.") (file-name-nondirectory . tramp-handle-file-name-nondirectory) ;; `file-name-sans-versions' performed by default handler. (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-notify-add-watch . ignore) - (file-notify-rm-watch . ignore) - (file-notify-valid-p . ignore) + (file-notify-add-watch . tramp-handle-file-notify-add-watch) + (file-notify-rm-watch . tramp-handle-file-notify-rm-watch) + (file-notify-valid-p . tramp-handle-file-notify-valid-p) (file-ownership-preserved-p . ignore) (file-readable-p . tramp-sudoedit-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) @@ -336,7 +336,7 @@ absolute file names." (if (and delete-by-moving-to-trash trash) (move-file-to-trash filename) (unless (tramp-sudoedit-send-command - v "rm" (tramp-compat-file-name-unquote localname)) + v "rm" "-f" (tramp-compat-file-name-unquote localname)) ;; Propagate the error. (with-current-buffer (tramp-get-connection-buffer v) (goto-char (point-min)) @@ -789,9 +789,6 @@ connection if a previous connection has died for some reason." (process-put p 'vector vec) (set-process-query-on-exit-flag p nil) - ;; Mark process for filelock. - (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds))) - ;; Set connection-local variables. (tramp-set-connection-local-variables vec) diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 1f41a926763..9c04abc8289 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -7,7 +7,7 @@ ;; Maintainer: Michael Albinus <michael.albinus@gmx.de> ;; Keywords: comm, processes ;; Package: tramp -;; Version: 2.5.2.28.1 +;; Version: 2.5.3-pre ;; Package-Requires: ((emacs "25.1")) ;; Package-Type: multi ;; URL: https://www.gnu.org/software/tramp/ @@ -40,7 +40,7 @@ ;; ./configure" to change them. ;;;###tramp-autoload -(defconst tramp-version "2.5.2.28.1" +(defconst tramp-version "2.5.3-pre" "This version of Tramp.") ;;;###tramp-autoload @@ -76,7 +76,7 @@ ;; Check for Emacs version. (let ((x (if (not (string-lessp emacs-version "25.1")) "ok" - (format "Tramp 2.5.2.28.1 is not fit for %s" + (format "Tramp 2.5.3-pre is not fit for %s" (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x))) |