[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/tramp 851269d 2/2: Tramp ELPA version 2.5.0.3 released
From: |
Michael Albinus |
Subject: |
[elpa] externals/tramp 851269d 2/2: Tramp ELPA version 2.5.0.3 released |
Date: |
Tue, 30 Mar 2021 06:22:46 -0400 (EDT) |
branch: externals/tramp
commit 851269dcfd7a564894ba4d4c2c7da8a97b40ce62
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>
Tramp ELPA version 2.5.0.3 released
---
test/tramp-tests.el | 84 ++++++-----
texi/tramp.texi | 303 ++++++++++++++++++++++++++++----------
texi/trampver.texi | 2 +-
tramp-adb.el | 2 -
tramp-cache.el | 28 ++--
tramp-cmds.el | 17 ++-
tramp-compat.el | 2 +-
tramp-crypt.el | 24 +++
tramp-fuse.el | 205 ++++++++++++++++++++++++++
tramp-gvfs.el | 1 -
tramp-integration.el | 24 ++-
tramp-rclone.el | 189 ++----------------------
tramp-sh.el | 404 ++++++++++++++-------------------------------------
tramp-smb.el | 7 -
tramp-sshfs.el | 367 ++++++++++++++++++++++++++++++++++++++++++++++
tramp-sudoedit.el | 22 +--
tramp.el | 164 ++++++++++++++++-----
trampver.el | 6 +-
18 files changed, 1187 insertions(+), 664 deletions(-)
diff --git a/test/tramp-tests.el b/test/tramp-tests.el
index 719e97d..3189fa1 100644
--- a/test/tramp-tests.el
+++ b/test/tramp-tests.el
@@ -2824,9 +2824,10 @@ This tests also `file-directory-p' and
`file-accessible-directory-p'."
(should (file-exists-p (expand-file-name "bla" tmp-name2)))
(should-error
(delete-directory tmp-name1 nil 'trash)
- ;; tramp-rclone.el calls the local `delete-directory'.
- ;; This raises another error.
- :type (if (tramp--test-rclone-p) 'error 'file-error))
+ ;; tramp-rclone.el and tramp-sshfs.el call the local
+ ;; `delete-directory'. This raises another error.
+ :type (if (or (tramp--test-rclone-p) (tramp--test-sshfs-p))
+ 'error 'file-error))
(delete-directory tmp-name1 'recursive 'trash)
(should-not (file-directory-p tmp-name1))
(should
@@ -3254,8 +3255,8 @@ This tests also `file-directory-p' and
`file-accessible-directory-p'."
(ignore-errors (delete-directory tmp-name1 'recursive))))))
;; Method "smb" supports `make-symbolic-link' only if the remote host
-;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el and
-;; tramp-rclone.el do not support symbolic links at all.
+;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el, tramp-rclone.el
+;; and tramp-sshfs.el do not support symbolic links at all.
(defmacro tramp--test-ignore-make-symbolic-link-error (&rest body)
"Run BODY, ignoring \"make-symbolic-link not supported\" file error."
(declare (indent defun) (debug (body)))
@@ -3536,7 +3537,7 @@ They might differ only in time attributes or directory
size."
This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(skip-unless (tramp--test-enabled))
(skip-unless
- (or (tramp--test-sh-p) (tramp--test-sudoedit-p)
+ (or (tramp--test-sh-p) (tramp--test-sshfs-p) (tramp--test-sudoedit-p)
;; Not all tramp-gvfs.el methods support changing the file mode.
(and
(tramp--test-gvfs-p)
@@ -4367,11 +4368,15 @@ This tests also `make-symbolic-link', `file-truename'
and `add-name-to-file'."
(and (featurep 'tramp-test-load) (unload-feature 'tramp-test-load))
(delete-file tmp-name))))))
+(defun tramp--test-shell-file-name ()
+ "Return default remote shell.."
+ (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
+
(ert-deftest tramp-test28-process-file ()
"Check `process-file'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
+ (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)
(tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
@@ -4388,25 +4393,27 @@ This tests also `make-symbolic-link', `file-truename'
and `add-name-to-file'."
(should-not (zerop (process-file "binary-does-not-exist")))
;; Return exit code.
(should (= 42 (process-file
- (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")
+ (tramp--test-shell-file-name)
nil nil nil "-c" "exit 42")))
;; Return exit code in case the process is interrupted,
;; and there's no indication for a signal describing string.
- (let (process-file-return-signal-string)
- (should
- (= (+ 128 2)
- (process-file
- (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")
- nil nil nil "-c" "kill -2 $$"))))
+ (unless (tramp--test-sshfs-p)
+ (let (process-file-return-signal-string)
+ (should
+ (= (+ 128 2)
+ (process-file
+ (tramp--test-shell-file-name)
+ nil nil nil "-c" "kill -2 $$")))))
;; Return string in case the process is interrupted and
;; there's an indication for a signal describing string.
- (let ((process-file-return-signal-string t))
- (should
- (string-match-p
- "Interrupt\\|Signal 2"
- (process-file
- (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")
- nil nil nil "-c" "kill -2 $$"))))
+ (unless (tramp--test-sshfs-p)
+ (let ((process-file-return-signal-string t))
+ (should
+ (string-match-p
+ "Interrupt\\|Signal 2"
+ (process-file
+ (tramp--test-shell-file-name)
+ nil nil nil "-c" "kill -2 $$")))))
(with-temp-buffer
(write-region "foo" nil tmp-name)
@@ -4450,7 +4457,7 @@ This tests also `make-symbolic-link', `file-truename' and
`add-name-to-file'."
"Check `start-file-process'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
+ (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)
(tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
@@ -4570,7 +4577,7 @@ If UNSTABLE is non-nil, the test is tagged as
`:unstable'."
"Check `make-process'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
+ (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)
(tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; `make-process' supports file name handlers since Emacs 27.
(skip-unless (tramp--test-emacs27-p))
@@ -4798,7 +4805,7 @@ INPUT, if non-nil, is a string sent to the process."
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
(skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
- (tramp--test-sh-p)))
+ (tramp--test-sh-p) (tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
@@ -4897,7 +4904,7 @@ INPUT, if non-nil, is a string sent to the process."
:tags '(:expensive-test :unstable)
(skip-unless (tramp--test-enabled))
(skip-unless nil)
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
+ (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)
(tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; Prior Emacs 27, `shell-command-dont-erase-buffer' wasn't working properly.
(skip-unless (tramp--test-emacs27-p))
@@ -5222,7 +5229,7 @@ Use direct async.")
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
(skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
- (tramp--test-sh-p)))
+ (tramp--test-sh-p) (tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; Since Emacs 26.1.
(skip-unless (and (fboundp 'connection-local-set-profile-variables)
@@ -5244,8 +5251,7 @@ Use direct async.")
(with-no-warnings
(connection-local-set-profile-variables
'remote-sh
- `((explicit-shell-file-name
- . ,(if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
+ `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
(explicit-sh-args . ("-c" "echo foo"))))
(connection-local-set-profiles
`(:application tramp
@@ -5279,7 +5285,7 @@ Use direct async.")
(ert-deftest tramp-test35-exec-path ()
"Check `exec-path' and `executable-find'."
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
+ (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)
(tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; Since Emacs 27.1.
(skip-unless (fboundp 'exec-path))
@@ -5819,6 +5825,11 @@ Additionally, ls does not support \"--dired\"."
"^\\(afp\\|davs?\\|smb\\)$"
(file-remote-p tramp-test-temporary-file-directory 'method))))
+(defun tramp--test-sshfs-p ()
+ "Check, whether the remote host is offered by sshfs.
+This requires restrictions of file name syntax."
+ (tramp-sshfs-file-name-p tramp-test-temporary-file-directory))
+
(defun tramp--test-sudoedit-p ()
"Check, whether the sudoedit method is used."
(tramp-sudoedit-file-name-p tramp-test-temporary-file-directory))
@@ -6114,7 +6125,6 @@ Use the `stat' command."
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
;; We cannot use `tramp-test-vec', because this fails during compilation.
(with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
(skip-unless (tramp-get-remote-stat v)))
@@ -6134,7 +6144,6 @@ Use the `perl' command."
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
;; We cannot use `tramp-test-vec', because this fails during compilation.
(with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
(skip-unless (tramp-get-remote-perl v)))
@@ -6157,7 +6166,6 @@ Use the `ls' command."
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
(let ((tramp-connection-properties
(append
@@ -6243,7 +6251,6 @@ Use the `stat' command."
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
;; We cannot use `tramp-test-vec', because this fails during compilation.
(with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
(skip-unless (tramp-get-remote-stat v)))
@@ -6267,7 +6274,6 @@ Use the `perl' command."
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
;; We cannot use `tramp-test-vec', because this fails during compilation.
(with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
(skip-unless (tramp-get-remote-perl v)))
@@ -6294,7 +6300,6 @@ Use the `ls' command."
(skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
(let ((tramp-connection-properties
(append
@@ -6335,6 +6340,7 @@ Use the `ls' command."
"Set \"process-name\" and \"process-buffer\" connection properties.
The values are derived from PROC. Run BODY.
This is needed in timer functions as well as process filters and sentinels."
+ ;; FIXME: For tramp-sshfs.el, `processp' does not work.
(declare (indent 1) (debug (processp body)))
`(let* ((v (tramp-get-connection-property ,proc "vector" nil))
(pname (tramp-get-connection-property v "process-name" nil))
@@ -6384,7 +6390,7 @@ process sentinels. They shall not disturb each other."
(define-key special-event-map [sigusr1] #'tramp--test-timeout-handler)
(let* (;; For the watchdog.
(default-directory (expand-file-name temporary-file-directory))
- (shell-file-name (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
+ (shell-file-name (tramp--test-shell-file-name))
;; It doesn't work on w32 systems.
(watchdog
(start-process-shell-command
@@ -6867,8 +6873,10 @@ If INTERACTIVE is non-nil, the tests are run
interactively."
;; * Work on skipped tests. Make a comment, when it is impossible.
;; * Revisit expensive tests, once problems in `tramp-error' are solved.
;; * Fix `tramp-test06-directory-file-name' for `ftp'.
-;; * Implement `tramp-test31-interrupt-process' for `adb' and for
-;; direct async processes.
+;; * Implement `tramp-test31-interrupt-process' for `adb', `sshfs' and
+;; for direct async processes.
+;; * Check, why direct async processes do not work for
+;; `tramp-test43-asynchronous-requests'.
;; * Fix `tramp-test44-threads'.
(provide 'tramp-tests)
diff --git a/texi/tramp.texi b/texi/tramp.texi
index 382feb8..7baf26c 100644
--- a/texi/tramp.texi
+++ b/texi/tramp.texi
@@ -126,6 +126,7 @@ Configuring @value{tramp} for use
* Inline methods:: Inline methods.
* External methods:: External methods.
* GVFS-based methods:: @acronym{GVFS}-based external methods.
+* FUSE-based methods:: @acronym{FUSE}-based external methods.
* Default Method:: Selecting a default method.
* Default User:: Selecting a default user.
* Default Host:: Selecting a default host.
@@ -139,6 +140,7 @@ Configuring @value{tramp} for use
Setting own connection related information.
* Remote programs:: How @value{tramp} finds and uses programs on
the remote host.
* Remote shell setup:: Remote shell setup hints.
+* FUSE setup:: @acronym{FUSE} setup hints.
* Android shell setup:: Android shell setup hints.
* Auto-save and Backup:: Auto-save and Backup.
* Keeping files encrypted:: Protect remote files by encryption.
@@ -433,7 +435,7 @@ remote host, when the buffer you call the process from has
a remote
@code{default-directory}.
-@anchor{Quick Start Guide: File name syntax}
+@anchor{Quick Start Guide File name syntax}
@section File name syntax
@cindex file name syntax
@@ -459,7 +461,7 @@ connection methods also support a notation for the port to
be used, in
which case it is written as @code{host#port}.
-@anchor{Quick Start Guide: @option{ssh} and @option{plink} methods}
+@anchor{Quick Start Guide ssh and plink methods}
@section Using @option{ssh} and @option{plink}
@cindex method @option{ssh}
@cindex @option{ssh} method
@@ -478,28 +480,31 @@ an @command{ssh} server:
@file{@trampfn{plink,user@@host,/path/to/file}}.
-@anchor{Quick Start Guide: @option{su}, @option{sudo} and @option{sg} methods}
-@section Using @option{su}, @option{sudo} and @option{sg}
+@anchor{Quick Start Guide su, sudo, doas and sg methods}
+@section Using @option{su}, @option{sudo}, @option{doas} and @option{sg}
@cindex method @option{su}
@cindex @option{su} method
@cindex method @option{sudo}
@cindex @option{sudo} method
+@cindex method @option{doas}
+@cindex @option{doas} method
@cindex method @option{sg}
@cindex @option{sg} method
Sometimes, it is necessary to work on your local host under different
permissions. For this, you can use the @option{su} or @option{sudo}
-connection method. Both methods use @samp{root} as default user name
-and the return value of @code{(system-name)} as default host name.
-Therefore, it is convenient to open a file as
+connection method. On OpenBSD systems, the @option{doas} connection
+method offers the same functionality. These methods use @samp{root}
+as default user name and the return value of @code{(system-name)} as
+default host name. Therefore, it is convenient to open a file as
@file{@trampfn{sudo,,/path/to/file}}.
The method @option{sg} stands for ``switch group''; here the user name
is used as the group to change to. The default host name is the same.
-@anchor{Quick Start Guide: @option{ssh}, @option{plink}, @option{su},
@option{sudo} and @option{sg} methods}
-@section Combining @option{ssh} or @option{plink} with @option{su} or
@option{sudo}
+@anchor{Quick Start Guide Combining ssh, plink, su, sudo and doas methods}
+@section Combining @option{ssh} or @option{plink} with @option{su},
@option{sudo} or @option{doas}
@cindex method @option{ssh}
@cindex @option{ssh} method
@cindex method @option{plink}
@@ -508,18 +513,20 @@ is used as the group to change to. The default host name
is the same.
@cindex @option{su} method
@cindex method @option{sudo}
@cindex @option{sudo} method
+@cindex method @option{doas}
+@cindex @option{doas} method
-If the @option{su} or @option{sudo} option should be performed on
-another host, it can be comnbined with a leading @option{ssh} or
-@option{plink} option. That means that @value{tramp} connects first to
-the other host with non-administrative credentials, and changes to
-administrative credentials on that host afterwards. In a simple case,
-the syntax looks like
+If the @option{su}, @option{sudo} or @option{doas} option should be
+performed on another host, it can be comnbined with a leading
+@option{ssh} or @option{plink} option. That means that @value{tramp}
+connects first to the other host with non-administrative credentials,
+and changes to administrative credentials on that host afterwards. In
+a simple case, the syntax looks like
@file{@value{prefix}ssh@value{postfixhop}user@@host|sudo@value{postfixhop}@value{postfix}/path/to/file}.
@xref{Ad-hoc multi-hops}.
-@anchor{Quick Start Guide: @option{sudoedit} method}
+@anchor{Quick Start Guide sudoedit method}
@section Using @command{sudoedit}
@cindex method @option{sudoedit}
@cindex @option{sudoedit} method
@@ -532,7 +539,7 @@ method, it is restricted to @samp{localhost} only, and it
does not
support external processes.
-@anchor{Quick Start Guide: @option{smb} method}
+@anchor{Quick Start Guide smb method}
@section Using @command{smbclient}
@cindex method @option{smb}
@cindex @option{smb} method
@@ -546,7 +553,7 @@ of the local file name is the share exported by the remote
host,
@samp{path} in this example.
-@anchor{Quick Start Guide: GVFS-based methods}
+@anchor{Quick Start Guide GVFS-based methods}
@section Using @acronym{GVFS}-based methods
@cindex methods, gvfs
@cindex gvfs-based methods
@@ -570,7 +577,7 @@ file system), @file{@trampfn{dav,user@@host,/path/to/file}},
@file{@trampfn{mtp,device,/path/to/file}} (for media devices).
-@anchor{Quick Start Guide: GNOME Online Accounts based methods}
+@anchor{Quick Start Guide GNOME Online Accounts based methods}
@section Using @acronym{GNOME} Online Accounts based methods
@cindex @acronym{GNOME} Online Accounts
@cindex method @option{gdrive}
@@ -590,21 +597,18 @@ account), or
@file{@trampfn{nextcloud,user@@host#8081,/path/to/file}}
(@samp{8081} stands for the port number) for OwnCloud/NextCloud files.
-@anchor{Quick Start Guide: Android}
-@section Using Android
-@cindex method @option{adb}
-@cindex @option{adb} method
-@cindex android
-
-An Android device, which is connected via USB to your local host, can
-be accessed via the @command{adb} command. No user or host name is
-needed. The file name syntax is @file{@trampfn{adb,,/path/to/file}}.
-
-
-@anchor{Quick Start Guide: @option{rclone} method}
-@section Using @command{rclone}
+@anchor{Quick Start Guide FUSE-based methods}
+@section Using @acronym{FUSE}-based methods
+@cindex methods, fuse
+@cindex fuse-based methods
@cindex method @option{rclone}
@cindex @option{rclone} method
+@cindex method @option{sshfs}
+@cindex @option{sshfs} method
+
+@acronym{FUSE, Filesystem in Userspace} allows users to mount a
+virtual file system. It is also used by @acronym{GVFS} internally,
+but here we discuss methods which do not use the @acronym{GVFS} API.
A convenient way to access system storages is the @command{rclone}
program. If you have configured a storage in @command{rclone} under a
@@ -612,6 +616,24 @@ name @samp{storage} (for example), you can access it via
the remote
file name syntax @file{@trampfn{rclone,storage,/path/to/file}}. User
names are not needed.
+On local hosts which have installed the @command{sshfs} client for
+mounting a file system based on @command{sftp}, this method can be
+used. All remote files are available via the local mount point.
+@value{tramp} aids in mounting the file system if it isn't mounted
+yet, and it supports the access with the usual file name syntax
+@file{@trampfn{sshfs,user@@host,/path/to/file}}.
+
+
+@anchor{Quick Start Guide Android}
+@section Using Android
+@cindex method @option{adb}
+@cindex @option{adb} method
+@cindex android
+
+An Android device, which is connected via USB to your local host, can
+be accessed via the @command{adb} command. No user or host name is
+needed. The file name syntax is @file{@trampfn{adb,,/path/to/file}}.
+
@node Configuration
@chapter Configuring @value{tramp}
@@ -650,6 +672,7 @@ may be used in your init file:
* Inline methods:: Inline methods.
* External methods:: External methods.
* GVFS-based methods:: @acronym{GVFS}-based external methods.
+* FUSE-based methods:: @acronym{FUSE}-based external methods.
* Default Method:: Selecting a default method.
Here we also try to help those who
don't have the foggiest which method
@@ -666,6 +689,7 @@ may be used in your init file:
Setting own connection related information.
* Remote programs:: How @value{tramp} finds and uses programs on
the remote host.
* Remote shell setup:: Remote shell setup hints.
+* FUSE setup:: @acronym{FUSE} setup hints.
* Android shell setup:: Android shell setup hints.
* Auto-save and Backup:: Auto-save and Backup.
* Keeping files encrypted:: Protect remote files by encryption.
@@ -1110,7 +1134,6 @@ UNC file name specification does not allow the
specification of a
different user name for authentication like the @command{smbclient}
can.
-
@item @option{adb}
@cindex method @option{adb}
@cindex @option{adb} method
@@ -1150,45 +1173,6 @@ specified using @file{device#42} host name syntax or
@value{tramp} can
use the default value as declared in @command{adb} command. Port
numbers are not applicable to Android devices connected through USB@.
-
-@item @option{rclone}
-@cindex method @option{rclone}
-@cindex @option{rclone} method
-
-@vindex tramp-rclone-program
-The program @command{rclone} allows to access different system
-storages in the cloud, see @url{https://rclone.org/} for a list of
-supported systems. If the @command{rclone} program isn't found in
-your @env{PATH} environment variable, you can tell @value{tramp} its
-absolute path via the user option @code{tramp-rclone-program}.
-
-A system storage must be configured via the @command{rclone config}
-command, outside Emacs. If you have configured a storage in
-@command{rclone} under a name @samp{storage} (for example), you could
-access it via the remote file name
-
-@example
-@trampfn{rclone,storage,/path/to/file}
-@end example
-
-User names are part of the @command{rclone} configuration, and not
-needed in the remote file name. If a user name is contained in the
-remote file name, it is ignored.
-
-Internally, @value{tramp} mounts the remote system storage at location
-@file{/tmp/tramp.rclone.storage}, with @file{storage} being the name
-of the configured system storage.
-
-Optional flags to the different @option{rclone} operations could be
-passed as connection property, @xref{Predefined connection
-information}. Supported properties are @t{"mount-args"},
-@t{"copyto-args"}, @t{"moveto-args"} and @t{"about-args"}.
-
-Access via @option{rclone} is slow. If you have an alternative method
-for accessing the system storage, you should use it.
-@ref{GVFS-based methods} for example, methods @option{gdrive} and
-@option{nextcloud}.
-
@end table
@@ -1200,8 +1184,8 @@ for accessing the system storage, you should use it.
@acronym{GVFS} is the virtual file system for the @acronym{GNOME}
Desktop, @uref{https://en.wikipedia.org/wiki/GVFS}. Remote files on
-@acronym{GVFS} are mounted locally through FUSE and @value{tramp} uses
-this locally mounted directory internally.
+@acronym{GVFS} are mounted locally through @acronym{FUSE} and
+@value{tramp} uses this locally mounted directory internally.
Emacs uses the D-Bus mechanism to communicate with @acronym{GVFS}@.
Emacs must have the message bus system, D-Bus integration active,
@@ -1317,6 +1301,88 @@ respectively:
@end defopt
+@node FUSE-based methods
+@section @acronym{FUSE}-based external methods
+@cindex methods, fuse
+@cindex fuse-based methods
+
+Besides @acronym{GVFS}, there are other virtual file systems using the
+@acronym{FUSE} interface. Remote files are mounted locally through
+@acronym{FUSE} and @value{tramp} uses this locally mounted directory
+internally. When possible, @value{tramp} maps the remote file names
+to their respective local file name, and applies the file name
+operation on them. For some of the file name operations this is not
+possible, @value{tramp} emulates those operations otherwise.
+
+@table @asis
+@item @option{rclone}
+@cindex method @option{rclone}
+@cindex @option{rclone} method
+
+@vindex tramp-rclone-program
+The program @command{rclone} allows to access different system
+storages in the cloud, see @url{https://rclone.org/} for a list of
+supported systems. If the @command{rclone} program isn't found in
+your @env{PATH} environment variable, you can tell @value{tramp} its
+absolute path via the user option @code{tramp-rclone-program}.
+
+A system storage must be configured via the @command{rclone config}
+command, outside Emacs. If you have configured a storage in
+@command{rclone} under a name @samp{storage} (for example), you could
+access it via the remote file name
+
+@example
+@trampfn{rclone,storage,/path/to/file}
+@end example
+
+User names are part of the @command{rclone} configuration, and not
+needed in the remote file name. If a user name is contained in the
+remote file name, it is ignored.
+
+Internally, @value{tramp} mounts the remote system storage at location
+@file{/tmp/tramp.rclone.storage}, with @file{storage} being the name
+of the configured system storage.
+
+The mount point and optional flags to the different @option{rclone}
+operations could be passed as connection properties, @xref{Setup of
+rclone method}.
+
+Access via @option{rclone} is slow. If you have an alternative method
+for accessing the system storage, you should use it.
+@ref{GVFS-based methods} for example, methods @option{gdrive} and
+@option{nextcloud}.
+
+@item @option{sshfs}
+@cindex method @option{sshfs}
+@cindex @option{sshfs} method
+
+@vindex tramp-sshfs-program
+On local hosts which have installed the @command{sshfs} client for
+mounting a file system based on @command{sftp}, this method can be
+used, see
+@url{https://github.com/libfuse/sshfs/blob/master/README.rst/}. If
+the @command{sshfs} program isn't found in your @env{PATH} environment
+variable, you can tell @value{tramp} its absolute path via the user
+option @code{tramp-sshfs-program}.
+
+All remote files are available via the local mount point.
+@value{tramp} aids in mounting the file system if it isn't mounted
+yet. The remote file name syntax is
+
+@example
+@trampfn{sshfs,user@@host#port,/path/to/file}
+@end example
+
+User name and port number are optional. This method does not support
+password handling, the file system must either be mounted already, or
+the connection must be established passwordless via ssh keys.
+
+The mount point and mount arguments could be passed as connection
+properties, @xref{Setup of sshfs method}.
+
+@end table
+
+
@node Default Method
@section Selecting a default method
@cindex default method
@@ -2102,6 +2168,13 @@ The default value of this property is @code{t} (not
specified in
@code{tramp-methods}). If the remote host runs native MS Windows,
this propery has no effect.
+@item @t{"mount-point"}
+
+The directory file name an @acronym{FUSE}-based file system is mounted
+on. The default value of this property is
+@t{"/tmp/tramp.method.user@@host#port"} (not specified in
+@code{tramp-methods}).
+
@item @t{"mount-args"}@*
@t{"copyto-args"}@*
@t{"moveto-args"}@*
@@ -2211,7 +2284,7 @@ be recomputed. To force @value{tramp} to recompute
afresh, call
By default, @value{tramp} uses the command @command{/bin/sh} for
starting a shell on the remote host. This can be changed by setting
-the connection property @t{"remote-shell"}; see @pxref{Predefined
+the connection property @t{"remote-shell"}; see @ref{Predefined
connection information}. If you want, for example, use
@command{/usr/bin/zsh} on a remote host, you might apply
@@ -2232,6 +2305,8 @@ which support this.
This approach has also the advantage, that settings in
@code{tramp-sh-extra-args} will be applied. For @command{zsh}, the
trouble with the shell prompt due to set zle options will be avoided.
+For @command{bash}, loading @file{~/.editrc} or @file{~/.inputrc} is
+suppressed.
Similar problems can happen with the local shell Tramp uses to create
a process. By default, it uses the command @command{/bin/sh} for
@@ -2430,7 +2505,6 @@ match the end of the connection buffer. Due to
performance reasons,
this search starts at the end of the buffer, and it is limited to 256
characters backwards.
-
@item Conflicting names for users and variables in @file{.profile}
When a user name is the same as a variable name in a local file, such
@@ -2440,7 +2514,6 @@ variable name to something different from the user name.
For example,
if the user name is @env{FRUMPLE}, then change the variable name to
@env{FRUMPLE_DIR}.
-
@item Non-Bourne commands in @file{.profile}
When the remote host's @file{.profile} is also used for shells other
@@ -2465,7 +2538,6 @@ To accommodate using non-Bourne shells on that remote,
use other
shell-specific config files. For example, bash can use
@file{~/.bash_profile} and ignore @file{.profile}.
-
@item Interactive shell prompt
@vindex INSIDE_EMACS@r{, environment variable}
@@ -2533,6 +2605,60 @@ where @samp{192.168.0.1} is the remote host IP address
@end table
+@node FUSE setup
+@section @acronym{FUSE} setup hints
+
+The @acronym{FUSE} file systems are mounted per default at
+@file{/tmp/tramp.method.user@@host#port}. The user name and port
+number are optional. If the file system is already mounted, it will
+be used as it is. If the mount point does not exist yet,
+@value{tramp} creates this directory.
+
+The mount point can be overwritten by the connection property
+@t{"mount-point"}, @ref{Predefined connection information}.
+Example:
+
+@lisp
+@group
+(add-to-list 'tramp-connection-properties
+ `(,(regexp-quote "@trampfn{sshfs,user@@host,}")
+ "mount-point"
+ ,(expand-file-name "sshfs.user@@host" user-emacs-directory)))
+@end group
+@end lisp
+
+
+@anchor{Setup of rclone method}
+@subsection @option{rclone} setup
+@cindex rclone setup
+
+The default arguments of the @command{rclone} operations
+@command{mount}, @command{coopyto}, @command{moveto} and
+@command{about} are declared in the variable @code{tramp-methods} as
+method specific parameters. Usually, they don't need to be overwritten.
+
+If needed, these parameters can be overwritten as connection
+properties @t{"mount-args"}, @t{"copyto-args"}, @t{"moveto-args"} and
+@t{"about-args"}, @xref{Predefined connection information}. All of
+them are list of strings.
+
+Be careful changing @t{"--dir-cache-time"}, this could delay
+visibility of files.
+
+
+@anchor{Setup of sshfs method}
+@subsection @option{sshfs} setup
+@cindex sshfs setup
+
+The method @option{sshfs} declares the mount arguments in the variable
+@code{tramp-methods}, passed to the @command{sshfs} command. This is
+a list of list of strings, and can be overwritten by the connection
+property @t{"mount-args"}, @xref{Predefined connection information}.
+
+Additionally, it declares also the arguments for running remote
+processes, using the @command{ssh} command. These don't need to be
+changed.
+
@node Android shell setup
@section Android shell setup hints
@cindex android shell setup for ssh
@@ -4197,6 +4323,7 @@ Disable excessive traces. Set @code{tramp-verbose} to 3
or lower,
default being 3. Increase trace levels temporarily when hunting for
bugs.
+
@item
@value{tramp} does not connect to the remote host
@@ -4448,6 +4575,7 @@ disable @samp{--color=yes} or @samp{--color=auto} in the
remote host's
@file{.bashrc} or @file{.profile}. Turn this alias on and off to see
if file name completion works.
+
@item
File name completion does not work in directories with large number of
files
@@ -4846,6 +4974,7 @@ In BBDB buffer, access an entry by pressing the key
@kbd{F}.
Thanks to @value{tramp} users for contributing to these recipes.
+
@item
Why saved multi-hop file names do not work in a new Emacs session?
@@ -4950,6 +5079,24 @@ In case you have installed it from its Git repository,
@ref{Recompilation}.
@item
+I get an error @samp{tramp-file-name-handler: Invalid function:
+tramp-compat-with-mutex}
+
+Likely, you have a running Emacs session with loaded @value{tramp},
+and you try to upgrade it to another version from GNU ELPA. Since
+@value{tramp} is not forward compatible, you must unload / reload it.
+Try the following steps:
+
+@example
+@kbd{M-x tramp-unload-tramp @key{RET}}
+@kbd{M-x load-library @key{RET} tramp @key{RET}}
+@end example
+
+If this doesn't work, you must restart Emacs with proper
+@code{load-path} for the new @value{tramp} version.
+
+
+@item
I get an error @samp{Remote file error: Forbidden reentrant call of Tramp}
@vindex remote-file-error
diff --git a/texi/trampver.texi b/texi/trampver.texi
index 580c390..dc41564 100644
--- a/texi/trampver.texi
+++ b/texi/trampver.texi
@@ -8,7 +8,7 @@
@c In the Tramp GIT, the version numbers are auto-frobbed from
@c tramp.el, and the bug report address is auto-frobbed from
@c configure.ac.
-@set trampver 2.5.0.2
+@set trampver 2.5.0.3
@set trampurl https://www.gnu.org/software/tramp/
@set tramp-bug-report-address tramp-devel@@gnu.org
@set emacsver 25.1
diff --git a/tramp-adb.el b/tramp-adb.el
index 6ec4d1f..aacf83e 100644
--- a/tramp-adb.el
+++ b/tramp-adb.el
@@ -44,7 +44,6 @@
:version "24.4"
:type 'string)
-;;;###tramp-autoload
(defcustom tramp-adb-connect-if-not-connected nil
"Try to run `adb connect' if provided device is not connected currently.
It is used for TCP/IP devices."
@@ -56,7 +55,6 @@ It is used for TCP/IP devices."
(defconst tramp-adb-method "adb"
"When this method name is used, forward all calls to Android Debug Bridge.")
-;;;###tramp-autoload
(defcustom tramp-adb-prompt "^[^#$\n\r]*[#$][[:space:]]"
"Regexp used as prompt in almquist shell."
:type 'regexp
diff --git a/tramp-cache.el b/tramp-cache.el
index dc71648..d754e73 100644
--- a/tramp-cache.el
+++ b/tramp-cache.el
@@ -162,16 +162,20 @@ Return DEFAULT if not set."
(tramp-message
key 8 "%s %s %s; inhibit: %s; cache used: %s; cached at: %s"
file property value remote-file-name-inhibit-cache cache-used cached-at)
+ ;; For analysis purposes, count the number of getting this file attribute.
(when (>= tramp-verbose 10)
(let* ((var (intern (concat "tramp-cache-get-count-" property)))
- (val (or (numberp (bound-and-true-p var))
- (progn
- (add-hook 'tramp-cache-unload-hook
- (lambda () (makunbound var)))
- 0))))
+ (val (or (and (boundp var) (numberp (symbol-value var))
+ (symbol-value var))
+ 0)))
(set var (1+ val))))
value))
+(add-hook 'tramp-cache-unload-hook
+ (lambda ()
+ (dolist (var (all-completions "tramp-cache-get-count-" obarray))
+ (unintern var obarray))))
+
;;;###tramp-autoload
(defun tramp-set-file-property (key file property value)
"Set the PROPERTY of FILE to VALUE, in the cache context of KEY.
@@ -186,16 +190,20 @@ Return VALUE."
;; We put the timestamp there.
(puthash property (cons (current-time) value) hash)
(tramp-message key 8 "%s %s %s" file property value)
+ ;; For analysis purposes, count the number of setting this file attribute.
(when (>= tramp-verbose 10)
(let* ((var (intern (concat "tramp-cache-set-count-" property)))
- (val (or (numberp (bound-and-true-p var))
- (progn
- (add-hook 'tramp-cache-unload-hook
- (lambda () (makunbound var)))
- 0))))
+ (val (or (and (boundp var) (numberp (symbol-value var))
+ (symbol-value var))
+ 0)))
(set var (1+ val))))
value))
+(add-hook 'tramp-cache-unload-hook
+ (lambda ()
+ (dolist (var (all-completions "tramp-cache-set-count-" obarray))
+ (unintern var obarray))))
+
;;;###tramp-autoload
(defun tramp-flush-file-property (key file property)
"Remove PROPERTY of FILE in the cache context of KEY."
diff --git a/tramp-cmds.el b/tramp-cmds.el
index f0bbe31..d208f0e 100644
--- a/tramp-cmds.el
+++ b/tramp-cmds.el
@@ -144,11 +144,18 @@ When called interactively, a Tramp connection has to be
selected."
;;;###tramp-autoload
(defun tramp-cleanup-this-connection ()
"Flush all connection related objects of the current buffer's connection."
+ ;; (declare (completion tramp-command-completion-p)))
(interactive)
(and (tramp-tramp-file-p default-directory)
(tramp-cleanup-connection
(tramp-dissect-file-name default-directory 'noexpand))))
+;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form.
+;;;###tramp-autoload
+(function-put
+ #'tramp-cleanup-this-connection 'completion-predicate
+ #'tramp-command-completion-p)
+
;;;###tramp-autoload
(defvar tramp-cleanup-all-connections-hook nil
"List of functions to be called after all Tramp connections are cleaned up.")
@@ -201,7 +208,6 @@ This includes password cache, file cache, connection cache,
buffers."
(dolist (name (tramp-list-remote-buffers))
(when (bufferp (get-buffer name)) (kill-buffer name))))
-;;;###tramp-autoload
(defcustom tramp-default-rename-alist nil
"Default target for renaming remote buffer file names.
This is an alist of cons cells (SOURCE . TARGET). The first
@@ -224,7 +230,6 @@ expression which always matches."
:type '(repeat (cons (choice :tag "Source regexp" regexp sexp)
(choice :tag "Target name" string (const nil)))))
-;;;###tramp-autoload
(defcustom tramp-confirm-rename-file-names t
"Whether renaming a buffer file name must be confirmed."
:group 'tramp
@@ -243,7 +248,7 @@ function returns nil"
(host (or (file-remote-p string 'host) ""))
item result)
(while (setq item (pop tdra))
- (when (string-match-p (or (eval (car item)) "") string)
+ (when (string-match-p (or (eval (car item) t) "") string)
(setq tdra nil
result
(format-spec
@@ -431,6 +436,7 @@ Interactively, TARGET is selected from
`tramp-default-rename-alist'
without confirmation if the prefix argument is non-nil.
For details, see `tramp-rename-files'."
+ ;; (declare (completion tramp-command-completion-p))
(interactive
(let ((source default-directory)
target
@@ -461,6 +467,11 @@ For details, see `tramp-rename-files'."
(tramp-rename-files default-directory target))
+;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form.
+;;;###tramp-autoload
+(function-put
+ #'tramp-rename-these-files 'completion-predicate #'tramp-command-completion-p)
+
;; Tramp version is useful in a number of situations.
;;;###tramp-autoload
diff --git a/tramp-compat.el b/tramp-compat.el
index 00e29bf..fce9e0b 100644
--- a/tramp-compat.el
+++ b/tramp-compat.el
@@ -70,7 +70,7 @@
It is the default value of `temporary-file-directory'."
;; We must return a local directory. If it is remote, we could run
;; into an infloop.
- (eval (car (get 'temporary-file-directory 'standard-value))))
+ (eval (car (get 'temporary-file-directory 'standard-value)) t))
(defsubst tramp-compat-make-temp-name ()
"Generate a local temporary file name (compat function)."
diff --git a/tramp-crypt.el b/tramp-crypt.el
index f8de708..1d8c0ad 100644
--- a/tramp-crypt.el
+++ b/tramp-crypt.el
@@ -112,6 +112,18 @@ initializing a new crypted remote directory."
"Non-nil when encryption support is available.")
(setq tramp-crypt-enabled (executable-find tramp-crypt-encfs-program))
+;; This function takes action since Emacs 28.1, when
+;; `read-extended-command-predicate' is set to
+;; `command-completion-default-include-p'.
+(defun tramp-crypt-command-completion-p (symbol _buffer)
+ "A predicate for Tramp interactive commands.
+They are completed by \"M-x TAB\" only when encryption support is enabled."
+ (and tramp-crypt-enabled
+ ;; `tramp-crypt-remove-directory' needs to be completed only in
+ ;; case we have already crypted directories.
+ (or (not (eq symbol #'tramp-crypt-remove-directory))
+ tramp-crypt-directories)))
+
;;;###tramp-autoload
(defconst tramp-crypt-encfs-config ".encfs6.xml"
"Encfs configuration file name.")
@@ -481,10 +493,17 @@ directory. File names will be also encrypted."
(setq tramp-crypt-directories (cons name tramp-crypt-directories)))
(tramp-register-file-name-handlers))
+;; `tramp-crypt-command-completion-p' is not autoloaded, and this
+;; setting isn't either.
+(function-put
+ #'tramp-crypt-add-directory 'completion-predicate
+ #'tramp-crypt-command-completion-p)
+
(defun tramp-crypt-remove-directory (name)
"Unmark remote directory NAME for encryption.
Existing files in that directory and its subdirectories will be
kept in their encrypted form."
+ ;; (declare (completion tramp-crypt-command-completion-p))
(interactive "DRemote directory name: ")
(unless tramp-crypt-enabled
(tramp-user-error nil "Feature is not enabled."))
@@ -498,6 +517,11 @@ kept in their encrypted form."
(setq tramp-crypt-directories (delete name tramp-crypt-directories))
(tramp-register-file-name-handlers)))
+;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form.
+(function-put
+ #'tramp-crypt-remove-directory 'completion-predicate
+ #'tramp-crypt-command-completion-p)
+
;; `auth-source' requires a user.
(defun tramp-crypt-dissect-file-name (name)
"Return a `tramp-file-name' structure for NAME.
diff --git a/tramp-fuse.el b/tramp-fuse.el
new file mode 100644
index 0000000..ec1db86
--- /dev/null
+++ b/tramp-fuse.el
@@ -0,0 +1,205 @@
+;;; tramp-fuse.el --- Tramp access functions for FUSE mounts -*-
lexical-binding:t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Michael Albinus <michael.albinus@gmx.de>
+;; Keywords: comm, processes
+;; Package: tramp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; These are helper functions for FUSE file systems.
+
+;;; Code:
+
+(require 'tramp)
+
+;; File name primitives.
+
+(defun tramp-fuse-handle-delete-directory
+ (directory &optional recursive trash)
+ "Like `delete-directory' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name directory) nil
+ (tramp-flush-directory-properties v localname)
+ (delete-directory (tramp-fuse-local-file-name directory) recursive trash)))
+
+(defun tramp-fuse-handle-delete-file (filename &optional trash)
+ "Like `delete-file' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (delete-file (tramp-fuse-local-file-name filename) trash)
+ (tramp-flush-file-properties v localname)))
+
+(defun tramp-fuse-handle-directory-files
+ (directory &optional full match nosort count)
+ "Like `directory-files' for Tramp files."
+ (unless (file-exists-p directory)
+ (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (when (file-directory-p directory)
+ (setq directory (file-name-as-directory (expand-file-name directory)))
+ (with-parsed-tramp-file-name directory nil
+ (let ((result
+ (tramp-compat-directory-files
+ (tramp-fuse-local-file-name directory) full match nosort count)))
+ ;; Massage the result.
+ (when full
+ (let ((local (concat "^" (regexp-quote (tramp-fuse-mount-point v))))
+ (remote (directory-file-name
+ (funcall
+ (if (tramp-compat-file-name-quoted-p directory)
+ #'tramp-compat-file-name-quote #'identity)
+ (file-remote-p directory)))))
+ (setq result
+ (mapcar
+ (lambda (x) (replace-regexp-in-string local remote x))
+ result))))
+ ;; Some storage systems do not return "." and "..".
+ (dolist (item '(".." "."))
+ (when (and (string-match-p (or match (regexp-quote item)) item)
+ (not
+ (member (if full (setq item (concat directory item)) item)
+ result)))
+ (setq result (cons item result))))
+ ;; Return result.
+ (if nosort result (sort result #'string<))))))
+
+(defun tramp-fuse-handle-file-attributes (filename &optional id-format)
+ "Like `file-attributes' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (with-tramp-file-property
+ v localname (format "file-attributes-%s" id-format)
+ (file-attributes (tramp-fuse-local-file-name filename) id-format))))
+
+(defun tramp-fuse-handle-file-executable-p (filename)
+ "Like `file-executable-p' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (with-tramp-file-property v localname "file-executable-p"
+ (file-executable-p (tramp-fuse-local-file-name filename)))))
+
+(defun tramp-fuse-handle-file-name-all-completions (filename directory)
+ "Like `file-name-all-completions' for Tramp files."
+ (all-completions
+ filename
+ (delete-dups
+ (append
+ (file-name-all-completions
+ filename (tramp-fuse-local-file-name directory))
+ ;; Some storage systems do not return "." and "..".
+ (let (result)
+ (dolist (item '(".." ".") result)
+ (when (string-prefix-p filename item)
+ (catch 'match
+ (dolist (elt completion-regexp-list)
+ (unless (string-match-p elt item) (throw 'match nil)))
+ (setq result (cons (concat item "/") result))))))))))
+
+(defun tramp-fuse-handle-file-readable-p (filename)
+ "Like `file-readable-p' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (with-tramp-file-property v localname "file-readable-p"
+ (file-readable-p (tramp-fuse-local-file-name filename)))))
+
+;; This function isn't used.
+(defun tramp-fuse-handle-insert-directory
+ (filename switches &optional wildcard full-directory-p)
+ "Like `insert-directory' for Tramp files."
+ (insert-directory
+ (tramp-fuse-local-file-name filename) switches wildcard full-directory-p)
+ (goto-char (point-min))
+ (while (search-forward (tramp-fuse-local-file-name filename) nil 'noerror)
+ (replace-match filename)))
+
+(defun tramp-fuse-handle-make-directory (dir &optional parents)
+ "Like `make-directory' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name dir) nil
+ (make-directory (tramp-fuse-local-file-name dir) parents)
+ ;; When PARENTS is non-nil, DIR could be a chain of non-existent
+ ;; directories a/b/c/... Instead of checking, we simply flush the
+ ;; whole file cache.
+ (tramp-flush-file-properties v localname)
+ (tramp-flush-directory-properties
+ v (if parents "/" (file-name-directory localname)))))
+
+
+;; File name helper functions.
+
+(defun tramp-fuse-mount-spec (vec)
+ "Return local mount spec of VEC."
+ (if-let ((host (tramp-file-name-host vec))
+ (user (tramp-file-name-user vec)))
+ (format "%s@%s:/" user host)
+ (format "%s:/" host)))
+
+(defun tramp-fuse-mount-point (vec)
+ "Return local mount point of VEC."
+ (or (tramp-get-connection-property vec "mount-point" nil)
+ (expand-file-name
+ (concat
+ tramp-temp-name-prefix
+ (tramp-file-name-method vec) "."
+ (when (tramp-file-name-user vec)
+ (concat (tramp-file-name-user-domain vec) "@"))
+ (tramp-file-name-host-port vec))
+ (tramp-compat-temporary-file-directory))))
+
+(defun tramp-fuse-mounted-p (vec)
+ "Check, whether fuse volume determined by VEC is mounted."
+ (when (tramp-get-connection-process vec)
+ ;; We cannot use `with-connection-property', because we don't want
+ ;; to cache a nil result.
+ (or (tramp-get-connection-property
+ (tramp-get-connection-process vec) "mounted" nil)
+ (let* ((default-directory (tramp-compat-temporary-file-directory))
+ (fuse (concat "fuse." (tramp-file-name-method vec)))
+ (mount (shell-command-to-string (format "mount -t %s" fuse))))
+ (tramp-message vec 6 "%s %s" "mount -t" fuse)
+ (tramp-message vec 6 "\n%s" mount)
+ (tramp-set-connection-property
+ (tramp-get-connection-process vec) "mounted"
+ (when (string-match
+ (format
+ "^\\(%s\\)\\s-" (regexp-quote (tramp-fuse-mount-spec vec)))
+ mount)
+ (match-string 1 mount)))))))
+
+(defun tramp-fuse-local-file-name (filename)
+ "Return local mount name of FILENAME."
+ (setq filename (tramp-compat-file-name-unquote (expand-file-name filename)))
+ (with-parsed-tramp-file-name filename nil
+ ;; As long as we call `tramp-*-maybe-open-connection' here,
+ ;; we cache the result.
+ (with-tramp-file-property v localname "local-file-name"
+ (funcall
+ (intern
+ (format "tramp-%s-maybe-open-connection" (tramp-file-name-method v)))
+ v)
+ (let ((quoted (tramp-compat-file-name-quoted-p localname))
+ (localname (tramp-compat-file-name-unquote localname)))
+ (funcall
+ (if quoted #'tramp-compat-file-name-quote #'identity)
+ (expand-file-name
+ (if (file-name-absolute-p localname)
+ (substring localname 1) localname)
+ (tramp-fuse-mount-point v)))))))
+
+(add-hook 'tramp-unload-hook
+ (lambda ()
+ (unload-feature 'tramp-fuse 'force)))
+
+(provide 'tramp-fuse)
+
+;;; tramp-fuse.el ends here
diff --git a/tramp-gvfs.el b/tramp-gvfs.el
index 9d4e04c..c4ec112 100644
--- a/tramp-gvfs.el
+++ b/tramp-gvfs.el
@@ -175,7 +175,6 @@ They are checked during start up via
(dbus-list-known-names :session))
(setq tramp-media-methods (delete method tramp-media-methods)))))
-;;;###tramp-autoload
(defcustom tramp-gvfs-zeroconf-domain "local"
"Zeroconf domain to be used for discovering services, like host names."
:group 'tramp
diff --git a/tramp-integration.el b/tramp-integration.el
index 64b5b48..2931b4f 100644
--- a/tramp-integration.el
+++ b/tramp-integration.el
@@ -49,6 +49,7 @@
(defvar recentf-exclude)
(defvar tramp-current-connection)
(defvar tramp-postfix-host-format)
+(defvar tramp-use-ssh-controlmaster-options)
;;; Fontification of `read-file-name':
@@ -231,7 +232,7 @@ NAME must be equal to `tramp-current-connection'."
(delete (info-lookup->mode-cache 'symbol 'tramp-info-lookup-mode)
(info-lookup->topic-cache 'symbol)))))
- (dolist (mode (mapcar 'car (info-lookup->topic-value 'symbol)))
+ (dolist (mode (mapcar #'car (info-lookup->topic-value 'symbol)))
;; Add `tramp-info-lookup-mode' to `other-modes' for either
;; `emacs-lisp-mode' itself, or to modes which use
;; `emacs-lisp-mode' as `other-modes'. Reset `info-lookup-cache'.
@@ -261,6 +262,23 @@ NAME must be equal to `tramp-current-connection'."
(delete (info-lookup->mode-cache 'symbol ',mode)
(info-lookup->topic-cache 'symbol))))))))
+;;; Integration of compile.el:
+
+;; Compilation processes use `accept-process-output' such a way that
+;; Tramp's parallel `accept-process-output' blocks. See last part of
+;; Bug#45518. So we don't use ssh ControlMaster options.
+(defun tramp-compile-disable-ssh-controlmaster-options ()
+ "Don't allow ssh ControlMaster while compiling."
+ (setq-local tramp-use-ssh-controlmaster-options nil))
+
+(with-eval-after-load 'compile
+ (add-hook 'compilation-mode-hook
+ #'tramp-compile-disable-ssh-controlmaster-options)
+ (add-hook 'tramp-integration-unload-hook
+ (lambda ()
+ (remove-hook 'compilation-start-hook
+ #'tramp-compile-disable-ssh-controlmaster-options))))
+
;;; Default connection-local variables for Tramp:
;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exists since Emacs 26.1.
@@ -277,7 +295,7 @@ NAME must be equal to `tramp-current-connection'."
(tramp-compat-funcall
'connection-local-set-profiles
- `(:application tramp)
+ '(:application tramp)
'tramp-connection-local-default-system-profile)
(defconst tramp-connection-local-default-shell-variables
@@ -293,7 +311,7 @@ NAME must be equal to `tramp-current-connection'."
(with-eval-after-load 'shell
(tramp-compat-funcall
'connection-local-set-profiles
- `(:application tramp)
+ '(:application tramp)
'tramp-connection-local-default-shell-profile))
(add-hook 'tramp-unload-hook
diff --git a/tramp-rclone.el b/tramp-rclone.el
index a7f4c9b..3b6de3e 100644
--- a/tramp-rclone.el
+++ b/tramp-rclone.el
@@ -35,14 +35,13 @@
;;; Code:
-(eval-when-compile (require 'cl-lib))
(require 'tramp)
+(require 'tramp-fuse)
;;;###tramp-autoload
(defconst tramp-rclone-method "rclone"
"When this method name is used, forward all calls to rclone mounts.")
-;;;###tramp-autoload
(defcustom tramp-rclone-program "rclone"
"Name of the rclone program."
:group 'tramp
@@ -77,11 +76,11 @@
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
(copy-file . tramp-rclone-handle-copy-file)
- (delete-directory . tramp-rclone-handle-delete-directory)
- (delete-file . tramp-rclone-handle-delete-file)
+ (delete-directory . tramp-fuse-handle-delete-directory)
+ (delete-file . tramp-fuse-handle-delete-file)
;; `diff-latest-backup-file' performed by default handler.
(directory-file-name . tramp-handle-directory-file-name)
- (directory-files . tramp-rclone-handle-directory-files)
+ (directory-files . tramp-fuse-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
(dired-compress-file . ignore)
@@ -90,15 +89,15 @@
(expand-file-name . tramp-handle-expand-file-name)
(file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
(file-acl . ignore)
- (file-attributes . tramp-rclone-handle-file-attributes)
+ (file-attributes . tramp-fuse-handle-file-attributes)
(file-directory-p . tramp-handle-file-directory-p)
(file-equal-p . tramp-handle-file-equal-p)
- (file-executable-p . tramp-rclone-handle-file-executable-p)
+ (file-executable-p . tramp-fuse-handle-file-executable-p)
(file-exists-p . tramp-handle-file-exists-p)
(file-in-directory-p . tramp-handle-file-in-directory-p)
(file-local-copy . tramp-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
- (file-name-all-completions . tramp-rclone-handle-file-name-all-completions)
+ (file-name-all-completions . tramp-fuse-handle-file-name-all-completions)
(file-name-as-directory . tramp-handle-file-name-as-directory)
(file-name-case-insensitive-p . tramp-handle-file-name-case-insensitive-p)
(file-name-completion . tramp-handle-file-name-completion)
@@ -110,7 +109,7 @@
(file-notify-rm-watch . ignore)
(file-notify-valid-p . ignore)
(file-ownership-preserved-p . ignore)
- (file-readable-p . tramp-rclone-handle-file-readable-p)
+ (file-readable-p . tramp-fuse-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@@ -124,7 +123,7 @@
(insert-file-contents . tramp-handle-insert-file-contents)
(load . tramp-handle-load)
(make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
- (make-directory . tramp-rclone-handle-make-directory)
+ (make-directory . tramp-fuse-handle-make-directory)
(make-directory-internal . ignore)
(make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
(make-process . ignore)
@@ -277,86 +276,6 @@ file names."
(list filename newname ok-if-already-exists keep-date
preserve-uid-gid preserve-extended-attributes))))
-(defun tramp-rclone-handle-delete-directory
- (directory &optional recursive trash)
- "Like `delete-directory' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name directory) nil
- (tramp-flush-directory-properties v localname)
- (delete-directory (tramp-rclone-local-file-name directory) recursive
trash)))
-
-(defun tramp-rclone-handle-delete-file (filename &optional trash)
- "Like `delete-file' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (delete-file (tramp-rclone-local-file-name filename) trash)
- (tramp-flush-file-properties v localname)))
-
-(defun tramp-rclone-handle-directory-files
- (directory &optional full match nosort count)
- "Like `directory-files' for Tramp files."
- (unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
- (when (file-directory-p directory)
- (setq directory (file-name-as-directory (expand-file-name directory)))
- (with-parsed-tramp-file-name directory nil
- (let ((result
- (tramp-compat-directory-files
- (tramp-rclone-local-file-name directory) full match nosort
count)))
- ;; Massage the result.
- (when full
- (let ((local (concat "^" (regexp-quote (tramp-rclone-mount-point v))))
- (remote (funcall (if (tramp-compat-file-name-quoted-p directory)
- #'tramp-compat-file-name-quote #'identity)
- (file-remote-p directory))))
- (setq result
- (mapcar
- (lambda (x) (replace-regexp-in-string local remote x))
- result))))
- ;; Some storage systems do not return "." and "..".
- (dolist (item '(".." "."))
- (when (and (string-match-p (or match (regexp-quote item)) item)
- (not
- (member (if full (setq item (concat directory item)) item)
- result)))
- (setq result (cons item result))))
- ;; Return result.
- (if nosort result (sort result #'string<))))))
-
-(defun tramp-rclone-handle-file-attributes (filename &optional id-format)
- "Like `file-attributes' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (with-tramp-file-property
- v localname (format "file-attributes-%s" id-format)
- (file-attributes (tramp-rclone-local-file-name filename) id-format))))
-
-(defun tramp-rclone-handle-file-executable-p (filename)
- "Like `file-executable-p' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (with-tramp-file-property v localname "file-executable-p"
- (file-executable-p (tramp-rclone-local-file-name filename)))))
-
-(defun tramp-rclone-handle-file-name-all-completions (filename directory)
- "Like `file-name-all-completions' for Tramp files."
- (all-completions
- filename
- (delete-dups
- (append
- (file-name-all-completions
- filename (tramp-rclone-local-file-name directory))
- ;; Some storage systems do not return "." and "..".
- (let (result)
- (dolist (item '(".." ".") result)
- (when (string-prefix-p filename item)
- (catch 'match
- (dolist (elt completion-regexp-list)
- (unless (string-match-p elt item) (throw 'match nil)))
- (setq result (cons (concat item "/") result))))))))))
-
-(defun tramp-rclone-handle-file-readable-p (filename)
- "Like `file-readable-p' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (with-tramp-file-property v localname "file-readable-p"
- (file-readable-p (tramp-rclone-local-file-name filename)))))
-
(defun tramp-rclone-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors
@@ -384,36 +303,6 @@ file names."
(when (and total free)
(list total free (- total free))))))))
-(defun tramp-rclone-handle-insert-directory
- (filename switches &optional wildcard full-directory-p)
- "Like `insert-directory' for Tramp files."
- (insert-directory
- (tramp-rclone-local-file-name filename) switches wildcard full-directory-p)
- (goto-char (point-min))
- (while (search-forward (tramp-rclone-local-file-name filename) nil 'noerror)
- (replace-match filename)))
-
-(defun tramp-rclone-handle-insert-file-contents
- (filename &optional visit beg end replace)
- "Like `insert-file-contents' for Tramp files."
- (let ((result
- (insert-file-contents
- (tramp-rclone-local-file-name filename) visit beg end replace)))
- (prog1
- (list (expand-file-name filename) (cadr result))
- (when visit (setq buffer-file-name filename)))))
-
-(defun tramp-rclone-handle-make-directory (dir &optional parents)
- "Like `make-directory' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name dir) nil
- (make-directory (tramp-rclone-local-file-name dir) parents)
- ;; When PARENTS is non-nil, DIR could be a chain of non-existent
- ;; directories a/b/c/... Instead of checking, we simply flush the
- ;; whole file cache.
- (tramp-flush-file-properties v localname)
- (tramp-flush-directory-properties
- v (if parents "/" (file-name-directory localname)))))
-
(defun tramp-rclone-handle-rename-file
(filename newname &optional ok-if-already-exists)
"Like `rename-file' for Tramp files."
@@ -431,50 +320,6 @@ file names."
;; File name conversions.
-(defun tramp-rclone-mount-point (vec)
- "Return local mount point of VEC."
- (expand-file-name
- (concat
- tramp-temp-name-prefix (tramp-file-name-method vec)
- "." (tramp-file-name-host vec))
- (tramp-compat-temporary-file-directory)))
-
-(defun tramp-rclone-mounted-p (vec)
- "Check, whether storage system determined by VEC is mounted."
- (when (tramp-get-connection-process vec)
- ;; We cannot use `with-connection-property', because we don't want
- ;; to cache a nil result.
- (or (tramp-get-connection-property
- (tramp-get-connection-process vec) "mounted" nil)
- (let* ((default-directory (tramp-compat-temporary-file-directory))
- (mount (shell-command-to-string "mount -t fuse.rclone")))
- (tramp-message vec 6 "%s" "mount -t fuse.rclone")
- (tramp-message vec 6 "\n%s" mount)
- (tramp-set-connection-property
- (tramp-get-connection-process vec) "mounted"
- (when (string-match
- (format
- "^\\(%s:\\S-*\\)" (regexp-quote (tramp-file-name-host vec)))
- mount)
- (match-string 1 mount)))))))
-
-(defun tramp-rclone-local-file-name (filename)
- "Return local mount name of FILENAME."
- (setq filename (tramp-compat-file-name-unquote (expand-file-name filename)))
- (with-parsed-tramp-file-name filename nil
- ;; As long as we call `tramp-rclone-maybe-open-connection' here,
- ;; we cache the result.
- (with-tramp-file-property v localname "local-file-name"
- (tramp-rclone-maybe-open-connection v)
- (let ((quoted (tramp-compat-file-name-quoted-p localname))
- (localname (tramp-compat-file-name-unquote localname)))
- (funcall
- (if quoted #'tramp-compat-file-name-quote #'identity)
- (expand-file-name
- (if (file-name-absolute-p localname)
- (substring localname 1) localname)
- (tramp-rclone-mount-point v)))))))
-
(defun tramp-rclone-remote-file-name (filename)
"Return FILENAME as used in the `rclone' command."
(setq filename (tramp-compat-file-name-unquote (expand-file-name filename)))
@@ -487,7 +332,7 @@ file names."
;; TODO: This shall be handled by `expand-file-name'.
(setq localname
(replace-regexp-in-string "^\\." "" (or localname "")))
- (format "%s%s" (tramp-rclone-mounted-p v) localname)))
+ (format "%s%s" (tramp-fuse-mounted-p v) localname)))
;; It is a local file name.
filename))
@@ -517,20 +362,18 @@ connection if a previous connection has died for some
reason."
(tramp-set-connection-local-variables vec)))
;; Create directory.
- (unless (file-directory-p (tramp-rclone-mount-point vec))
- (make-directory (tramp-rclone-mount-point vec) 'parents))
+ (unless (file-directory-p (tramp-fuse-mount-point vec))
+ (make-directory (tramp-fuse-mount-point vec) 'parents))
;; Mount. This command does not return, so we use 0 as
;; DESTINATION of `tramp-call-process'.
- (unless (tramp-rclone-mounted-p vec)
+ (unless (tramp-fuse-mounted-p vec)
(apply
#'tramp-call-process
vec tramp-rclone-program nil 0 nil
- (delq nil
- `("mount" ,(concat host ":/")
- ,(tramp-rclone-mount-point vec)
- ;; This could be nil.
- ,@(tramp-get-method-parameter vec 'tramp-mount-args))))
+ "mount" (tramp-fuse-mount-spec vec)
+ (tramp-fuse-mount-point vec)
+ (tramp-get-method-parameter vec 'tramp-mount-args))
(while (not (file-exists-p (tramp-make-tramp-file-name vec 'noloc)))
(tramp-cleanup-connection vec 'keep-debug 'keep-password))
diff --git a/tramp-sh.el b/tramp-sh.el
index 5730199..1764f2e 100644
--- a/tramp-sh.el
+++ b/tramp-sh.el
@@ -46,7 +46,6 @@
(defconst tramp-default-remote-shell "/bin/sh"
"The default remote shell Tramp applies.")
-;;;###tramp-autoload
(defcustom tramp-inline-compress-start-size 4096
"The minimum size of compressing where inline transfer.
When inline transfer, compress transferred data of file whose
@@ -56,23 +55,12 @@ If it is nil, no compression at all will be applied."
:group 'tramp
:type '(choice (const nil) integer))
-;;;###tramp-autoload
(defcustom tramp-copy-size-limit 10240
"Maximum file size where inline copying is preferred to an out-of-the-band
copy.
If it is nil, out-of-the-band copy will be used without a check."
:group 'tramp
:type '(choice (const nil) integer))
-;;;###tramp-autoload
-(defcustom tramp-terminal-type "dumb"
- "Value of TERM environment variable for logging in to remote host.
-Because Tramp wants to parse the output of the remote shell, it is easily
-confused by ANSI color escape sequences and suchlike. Often, shell init
-files conditionalize this setup based on the TERM environment variable."
- :group 'tramp
- :type 'string)
-
-;;;###tramp-autoload
(defcustom tramp-histfile-override "~/.tramp_history"
"When invoking a shell, override the HISTFILE with this value.
When setting to a string, it redirects the shell history to that
@@ -115,7 +103,6 @@ detected as prompt when being sent on echoing hosts,
therefore.")
(defconst tramp-end-of-heredoc (md5 tramp-end-of-output)
"String used to recognize end of heredoc strings.")
-;;;###tramp-autoload
(defcustom tramp-use-ssh-controlmaster-options t
"Whether to use `tramp-ssh-controlmaster-options'.
Set it to nil, if you use Control* or Proxy* options in your ssh
@@ -477,70 +464,6 @@ The string is used in `tramp-methods'.")
(tramp-set-completion-function "psftp" tramp-completion-function-alist-ssh)
(tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh))
-;; "getconf PATH" yields:
-;; HP-UX:
/usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
-;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
-;; GNU/Linux (Debian, Suse, RHEL): /bin:/usr/bin
-;; FreeBSD, DragonFly: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
-;; FreeBSD 12.1, Darwin: /usr/bin:/bin:/usr/sbin:/sbin
-;; IRIX64: /usr/bin
-;; QNAP QTS: ---
-;; Hydra: /run/current-system/sw/bin:/bin:/usr/bin
-;;;###tramp-autoload
-(defcustom tramp-remote-path
- '(tramp-default-remote-path "/bin" "/usr/bin" "/sbin" "/usr/sbin"
- "/usr/local/bin" "/usr/local/sbin" "/local/bin" "/local/freeware/bin"
- "/local/gnu/bin" "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin"
- "/opt/bin" "/opt/sbin" "/opt/local/bin")
- "List of directories to search for executables on remote host.
-For every remote host, this variable will be set buffer local,
-keeping the list of existing directories on that host.
-
-You can use \"~\" in this list, but when searching for a shell which groks
-tilde expansion, all directory names starting with \"~\" will be ignored.
-
-`Default Directories' represent the list of directories given by
-the command \"getconf PATH\". It is recommended to use this
-entry on head of this list, because these are the default
-directories for POSIX compatible commands. On remote hosts which
-do not offer the getconf command (like cygwin), the value
-\"/bin:/usr/bin\" is used instead. This entry is represented in
-the list by the special value `tramp-default-remote-path'.
-
-`Private Directories' are the settings of the $PATH environment,
-as given in your `~/.profile'. This entry is represented in
-the list by the special value `tramp-own-remote-path'."
- :group 'tramp
- :type '(repeat (choice
- (const :tag "Default Directories" tramp-default-remote-path)
- (const :tag "Private Directories" tramp-own-remote-path)
- (string :tag "Directory"))))
-
-;;;###tramp-autoload
-(defcustom tramp-remote-process-environment
- '("ENV=''" "TMOUT=0" "LC_CTYPE=''"
- "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat"
- "autocorrect=" "correct=")
- "List of environment variables to be set on the remote host.
-
-Each element should be a string of the form ENVVARNAME=VALUE. An
-entry ENVVARNAME= disables the corresponding environment variable,
-which might have been set in the init files like ~/.profile.
-
-Special handling is applied to some environment variables,
-which should not be set here:
-
-The PATH environment variable should be set via `tramp-remote-path'.
-
-The TERM environment variable should be set via `tramp-terminal-type'.
-
-The INSIDE_EMACS environment variable will automatically be set
-based on the Tramp and Emacs versions, and should not be set here."
- :group 'tramp
- :version "26.1"
- :type '(repeat string))
-
-;;;###tramp-autoload
(defcustom tramp-sh-extra-args
'(("/bash\\'" . "-noediting -norc -noprofile")
("/zsh\\'" . "-f +Z -V"))
@@ -2370,53 +2293,29 @@ The method used must be an out-of-band method."
(setq listener (number-to-string (+ 50000 (random 10000))))))
;; Compose copy command.
- (setq host (or host "")
- user (or user "")
- port (or port "")
- spec (format-spec-make
- ?t (tramp-get-connection-property
- (tramp-get-connection-process v) "temp-file" ""))
- options (format-spec (tramp-ssh-controlmaster-options v) spec)
- spec (format-spec-make
- ?h host ?u user ?p port ?r listener ?c options
- ?k (if keep-date " " "")
+ (setq options
+ (format-spec
+ (tramp-ssh-controlmaster-options v)
+ (format-spec-make
+ ?t (tramp-get-connection-property
+ (tramp-get-connection-process v) "temp-file" "")))
+ spec (list
+ ?h (or host "") ?u (or user "") ?p (or port "")
+ ?r listener ?c options ?k (if keep-date " " "")
?n (concat "2>" (tramp-get-remote-null-device v)))
copy-program (tramp-get-method-parameter v 'tramp-copy-program)
copy-keep-date (tramp-get-method-parameter
v 'tramp-copy-keep-date)
-
copy-args
- (delete
- ;; " " has either been a replacement of "%k" (when
- ;; keep-date argument is non-nil), or a replacement
- ;; for the whole keep-date sublist.
- " "
- (dolist
- (x (tramp-get-method-parameter v 'tramp-copy-args) copy-args)
- (setq copy-args
- (append
- copy-args
- (let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
- (if (member "" y) '(" ") y))))))
-
- copy-env
- (delq
- nil
- (mapcar
- (lambda (x)
- (setq x (mapcar (lambda (y) (format-spec y spec)) x))
- (unless (member "" x) (string-join x " ")))
- (tramp-get-method-parameter v 'tramp-copy-env)))
-
+ ;; " " has either been a replacement of "%k" (when
+ ;; keep-date argument is non-nil), or a replacement for
+ ;; the whole keep-date sublist.
+ (delete " " (apply #'tramp-expand-args v 'tramp-copy-args spec))
+ copy-env (apply #'tramp-expand-args v 'tramp-copy-env spec)
remote-copy-program
- (tramp-get-method-parameter v 'tramp-remote-copy-program))
-
- (dolist (x (tramp-get-method-parameter v 'tramp-remote-copy-args))
- (setq remote-copy-args
- (append
- remote-copy-args
- (let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
- (if (member "" y) '(" ") y)))))
+ (tramp-get-method-parameter v 'tramp-remote-copy-program)
+ remote-copy-args
+ (apply #'tramp-expand-args v 'tramp-remote-copy-args spec))
;; Check for local copy program.
(unless (executable-find copy-program)
@@ -2462,10 +2361,11 @@ The method used must be an out-of-band method."
v "process-name" (buffer-name (current-buffer)))
(tramp-set-connection-property
v "process-buffer" (current-buffer))
- (while copy-env
+ (when copy-env
(tramp-message
- orig-vec 6 "%s=\"%s\"" (car copy-env) (cadr copy-env))
- (setenv (pop copy-env) (pop copy-env)))
+ orig-vec 6 "%s=\"%s\""
+ (car copy-env) (string-join (cdr copy-env) " "))
+ (setenv (car copy-env) (string-join (cdr copy-env) " ")))
(setq
copy-args
(append
@@ -3754,6 +3654,8 @@ Fall back to normal file name handler if no Tramp handler
exists."
(setq file-name (expand-file-name file-name))
(with-parsed-tramp-file-name file-name nil
(let ((default-directory (file-name-directory file-name))
+ (process-environment
+ (cons "GIO_USE_FILE_MONITOR=help" process-environment))
command events filter p sequence)
(cond
;; "inotifywait".
@@ -3786,18 +3688,6 @@ Fall back to normal file name handler if no Tramp
handler exists."
'(created changed changes-done-hint moved deleted))
((memq 'attribute-change flags) '(attribute-changed)))
sequence `(,command "monitor" ,localname)))
- ;; "gvfs-monitor-dir".
- ((setq command (tramp-get-remote-gvfs-monitor-dir v))
- (setq filter #'tramp-sh-gvfs-monitor-dir-process-filter
- events
- (cond
- ((and (memq 'change flags) (memq 'attribute-change flags))
- '(created changed changes-done-hint moved deleted
- attribute-changed))
- ((memq 'change flags)
- '(created changed changes-done-hint moved deleted))
- ((memq 'attribute-change flags) '(attribute-changed)))
- sequence `(,command ,localname)))
;; None.
(t (tramp-error
v 'file-notify-error
@@ -3830,10 +3720,6 @@ Fall back to normal file name handler if no Tramp
handler exists."
(unless (process-live-p p)
(tramp-error
p 'file-notify-error "Monitoring not supported for `%s'" file-name))
- ;; Set "gio-file-monitor" property if needed.
- (when (string-equal (file-name-nondirectory command) "gio")
- (tramp-set-connection-property
- p "gio-file-monitor" (tramp-get-remote-gio-file-monitor v)))
p))))
(defun tramp-sh-gio-monitor-process-filter (proc string)
@@ -3854,91 +3740,64 @@ Fall back to normal file name handler if no Tramp
handler exists."
"changes done" "changes-done-hint" string)
string (tramp-compat-string-replace
"renamed to" "moved" string))
- ;; https://bugs.launchpad.net/bugs/1742946
- (when
- (string-match-p "Monitoring not supported\\|No locations given" string)
- (delete-process proc))
-
- ;; Delete empty lines.
- (setq string (tramp-compat-string-replace "\n\n" "\n" string))
-
- (while (string-match
- (eval-when-compile
- (concat "^[^:]+:"
- "[[:space:]]\\([^:]+\\):"
- "[[:space:]]" (regexp-opt tramp-gio-events t)
- "\\([[:space:]]\\([^:]+\\)\\)?$"))
- string)
-
- (let* ((file (match-string 1 string))
- (file1 (match-string 4 string))
- (object
- (list
- proc
- (list
- (intern-soft (match-string 2 string)))
- ;; File names are returned as absolute paths. We must
- ;; add the remote prefix.
- (concat remote-prefix file)
- (when file1 (concat remote-prefix file1)))))
- (setq string (replace-match "" nil nil string))
- ;; Usually, we would add an Emacs event now. Unfortunately,
- ;; `unread-command-events' does not accept several events at
- ;; once. Therefore, we apply the handler directly.
- (when (member (cl-caadr object) events)
- (tramp-compat-funcall
- (lookup-key special-event-map [file-notify])
- `(file-notify ,object file-notify-callback)))))
- ;; Save rest of the string.
- (when (zerop (length string)) (setq string nil))
- (when string (tramp-message proc 10 "Rest string:\n%s" string))
- (process-put proc 'rest-string string)))
-
-(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string)
- "Read output from \"gvfs-monitor-dir\" and add corresponding \
-`file-notify' events."
- (let ((events (process-get proc 'events))
- (remote-prefix
- (with-current-buffer (process-buffer proc)
- (file-remote-p default-directory)))
- (rest-string (process-get proc 'rest-string)))
- (when rest-string
- (tramp-message proc 10 "Previous string:\n%s" rest-string))
- (tramp-message proc 6 "%S\n%s" proc string)
- (setq string (concat rest-string string)
- ;; Attribute change is returned in unused wording.
- string (tramp-compat-string-replace
- "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
-
- (while (string-match
- (concat "^[\n\r]*"
- "Directory Monitor Event:[\n\r]+"
- "Child = \\([^\n\r]+\\)[\n\r]+"
- "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
- "Event = \\([^[:blank:]]+\\)[\n\r]+")
- string)
- (let* ((file (match-string 1 string))
- (file1 (match-string 3 string))
- (object
- (list
- proc
- (list
- (intern-soft
- (tramp-compat-string-replace
- "_" "-" (downcase (match-string 4 string)))))
- ;; File names are returned as absolute paths. We must
- ;; add the remote prefix.
- (concat remote-prefix file)
- (when file1 (concat remote-prefix file1)))))
- (setq string (replace-match "" nil nil string))
- ;; Usually, we would add an Emacs event now. Unfortunately,
- ;; `unread-command-events' does not accept several events at
- ;; once. Therefore, we apply the handler directly.
- (when (member (cl-caadr object) events)
- (tramp-compat-funcall
- (lookup-key special-event-map [file-notify])
- `(file-notify ,object file-notify-callback)))))
+ (catch 'doesnt-work
+ ;; https://bugs.launchpad.net/bugs/1742946
+ (when
+ (string-match-p "Monitoring not supported\\|No locations given"
string)
+ (delete-process proc)
+ (throw 'doesnt-work nil))
+
+ ;; Determine monitor name.
+ (unless (tramp-connection-property-p proc "gio-file-monitor")
+ (cond
+ ;; We have seen this only on cygwin gio, which uses the
+ ;; GPollFileMonitor.
+ ((string-match
+ "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string)
+ (tramp-set-connection-property
+ proc "gio-file-monitor" 'GPollFileMonitor))
+ ;; TODO: What happens, if several monitor names are reported?
+ ((string-match "\
+Supported arguments for GIO_USE_FILE_MONITOR environment variable:
+\\s-*\\([[:alpha:]]+\\) - 20" string)
+ (tramp-set-connection-property
+ proc "gio-file-monitor"
+ (intern
+ (format "G%sFileMonitor" (capitalize (match-string 1 string))))))
+ (t (throw 'doesnt-work nil)))
+ (setq string (replace-match "" nil nil string)))
+
+ ;; Delete empty lines.
+ (setq string (tramp-compat-string-replace "\n\n" "\n" string))
+
+ (while (string-match
+ (eval-when-compile
+ (concat "^[^:]+:"
+ "[[:space:]]\\([^:]+\\):"
+ "[[:space:]]" (regexp-opt tramp-gio-events t)
+ "\\([[:space:]]\\([^:]+\\)\\)?$"))
+ string)
+
+ (let* ((file (match-string 1 string))
+ (file1 (match-string 4 string))
+ (object
+ (list
+ proc
+ (list
+ (intern-soft (match-string 2 string)))
+ ;; File names are returned as absolute paths. We
+ ;; must add the remote prefix.
+ (concat remote-prefix file)
+ (when file1 (concat remote-prefix file1)))))
+ (setq string (replace-match "" nil nil string))
+ ;; Usually, we would add an Emacs event now. Unfortunately,
+ ;; `unread-command-events' does not accept several events at
+ ;; once. Therefore, we apply the handler directly.
+ (when (member (cl-caadr object) events)
+ (tramp-compat-funcall
+ (lookup-key special-event-map [file-notify])
+ `(file-notify ,object file-notify-callback))))))
;; Save rest of the string.
(when (zerop (length string)) (setq string nil))
@@ -4918,7 +4777,7 @@ If there is just some editing, retry it after 5 seconds."
(progn
(tramp-message
vec 5 "Cannot timeout session, trying it again in %s seconds." 5)
- (run-at-time 5 nil 'tramp-timeout-session vec))
+ (run-at-time 5 nil #'tramp-timeout-session vec))
(tramp-message
vec 3 "Timeout session %s" (tramp-make-tramp-file-name vec 'noloc))
(tramp-cleanup-connection vec 'keep-debug nil 'keep-processes)))
@@ -5049,19 +4908,17 @@ connection if a previous connection has died for some
reason."
(l-domain (tramp-file-name-domain hop))
(l-host (tramp-file-name-host hop))
(l-port (tramp-file-name-port hop))
- (login-program
- (tramp-get-method-parameter hop 'tramp-login-program))
- (login-args
- (tramp-get-method-parameter hop 'tramp-login-args))
(remote-shell
(tramp-get-method-parameter hop 'tramp-remote-shell))
(extra-args (tramp-get-sh-extra-args remote-shell))
(async-args
- (tramp-get-method-parameter hop 'tramp-async-args))
+ (tramp-compat-flatten-tree
+ (tramp-get-method-parameter hop 'tramp-async-args)))
(connection-timeout
(tramp-get-method-parameter
hop 'tramp-connection-timeout))
- (command login-program)
+ (command
+ (tramp-get-method-parameter hop '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
@@ -5075,11 +4932,7 @@ connection if a previous connection has died for some
reason."
(with-tramp-connection-property
(tramp-get-process vec) "temp-file"
(tramp-compat-make-temp-name)))
- spec r-shell)
-
- ;; Add arguments for asynchronous processes.
- (when (and process-name async-args)
- (setq login-args (append async-args login-args)))
+ r-shell)
;; Check, whether there is a restricted shell.
(dolist (elt tramp-restricted-shell-hosts-alist)
@@ -5104,31 +4957,28 @@ connection if a previous connection has died for some
reason."
;; Replace `login-args' place holders.
(setq
- l-host (or l-host "")
- l-user (or l-user "")
- l-port (or l-port "")
- spec (format-spec-make ?t tmpfile)
- options (format-spec options spec)
- spec (format-spec-make
- ?h l-host ?u l-user ?p l-port ?c options
- ?l (concat remote-shell " " extra-args " -i"))
command
- (concat
- ;; We do not want to see the trailing local
- ;; prompt in `start-file-process'.
- (unless r-shell "exec ")
- command " "
- (mapconcat
- (lambda (x)
- (setq x (mapcar (lambda (y) (format-spec y spec)) x))
- (unless (member "" x) (string-join x " ")))
- login-args " ")
- ;; Local shell could be a Windows COMSPEC. It
- ;; doesn't know the ";" syntax, but we must exit
- ;; always for `start-file-process'. It could
- ;; also be a restricted shell, which does not
- ;; allow "exec".
- (when r-shell " && exit || exit")))
+ (mapconcat
+ #'identity
+ (append
+ ;; We do not want to see the trailing local
+ ;; prompt in `start-file-process'.
+ (unless r-shell '("exec"))
+ `(,command)
+ ;; Add arguments for asynchronous processes.
+ (when process-name async-args)
+ (tramp-expand-args
+ hop 'tramp-login-args
+ ?h (or l-host "") ?u (or l-user "") ?p (or l-port "")
+ ?c (format-spec options (format-spec-make ?t tmpfile))
+ ?l (concat remote-shell " " extra-args " -i"))
+ ;; Local shell could be a Windows COMSPEC. It
+ ;; doesn't know the ";" syntax, but we must
+ ;; exit always for `start-file-process'. It
+ ;; could also be a restricted shell, which does
+ ;; not allow "exec".
+ (when r-shell '("&&" "exit" "||" "exit")))
+ " "))
;; Send the command.
(tramp-message vec 3 "Sending command `%s'" command)
@@ -5149,7 +4999,7 @@ connection if a previous connection has died for some
reason."
(when (tramp-get-connection-property p "session-timeout" nil)
(run-at-time
(tramp-get-connection-property p "session-timeout" nil) nil
- 'tramp-timeout-session vec))
+ #'tramp-timeout-session vec))
;; Make initial shell settings.
(tramp-open-connection-setup-interactive-shell p vec)
@@ -5469,7 +5319,7 @@ Nonexistent directories are removed from spec."
(progn
(tramp-message
vec 3
- "`getconf PATH' not successful, using default value \"%s\"."
+ "`getconf PATH' not successful, using default value
\"%s\"."
"/bin:/usr/bin")
"/bin:/usr/bin"))))
(own-remote-path
@@ -5756,42 +5606,6 @@ This command is returned only if
`delete-by-moving-to-trash' is non-nil."
(tramp-message vec 5 "Finding a suitable `gio-monitor' command")
(tramp-find-executable vec "gio" (tramp-get-remote-path vec) t t)))
-(defun tramp-get-remote-gio-file-monitor (vec)
- "Determine remote GFileMonitor."
- (with-tramp-connection-property vec "gio-file-monitor"
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 5 "Finding the used GFileMonitor")
- (when-let ((gio (tramp-get-remote-gio-monitor vec)))
- ;; Search for the used FileMonitor. There is no known way to
- ;; get this information directly from gio, so we check for
- ;; linked libraries of libgio.
- (when (tramp-send-command-and-check vec (concat "ldd " gio))
- (goto-char (point-min))
- (when (re-search-forward "\\S-+/libgio\\S-+")
- (when (tramp-send-command-and-check
- vec (concat "strings " (match-string 0)))
- (goto-char (point-min))
- (re-search-forward
- (format
- "^%s$"
- (regexp-opt
- '("GFamFileMonitor" "GFenFileMonitor"
- "GInotifyFileMonitor" "GKqueueFileMonitor")))
- nil 'noerror)
- (intern (match-string 0)))))))))
-
-(defun tramp-get-remote-gvfs-monitor-dir (vec)
- "Determine remote `gvfs-monitor-dir' command."
- (with-tramp-connection-property vec "gvfs-monitor-dir"
- (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command")
- ;; We distinguish "gvfs-monitor-dir.exe" from cygwin in order to
- ;; establish better timeouts in filenotify-tests.el. Any better
- ;; distinction approach would be welcome!
- (or (tramp-find-executable
- vec "gvfs-monitor-dir.exe" (tramp-get-remote-path vec) t t)
- (tramp-find-executable
- vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t))))
-
(defun tramp-get-remote-inotifywait (vec)
"Determine remote `inotifywait' command."
(with-tramp-connection-property vec "inotifywait"
diff --git a/tramp-smb.el b/tramp-smb.el
index 6935955..6fbf088 100644
--- a/tramp-smb.el
+++ b/tramp-smb.el
@@ -60,20 +60,17 @@
tramp-smb-method
'((tramp-parse-netrc "~/.netrc"))))
-;;;###tramp-autoload
(defcustom tramp-smb-program "smbclient"
"Name of SMB client to run."
:group 'tramp
:type 'string)
-;;;###tramp-autoload
(defcustom tramp-smb-acl-program "smbcacls"
"Name of SMB acls to run."
:group 'tramp
:type 'string
:version "24.4")
-;;;###tramp-autoload
(defcustom tramp-smb-conf null-device
"Path of the \"smb.conf\" file.
If it is nil, no \"smb.conf\" will be added to the `tramp-smb-program'
@@ -81,7 +78,6 @@ call, letting the SMB client use the default one."
:group 'tramp
:type '(choice (const nil) (file :must-match t)))
-;;;###tramp-autoload
(defcustom tramp-smb-options nil
"List of additional options.
They are added to the `tramp-smb-program' call via \"--option '...'\".
@@ -305,7 +301,6 @@ See `tramp-actions-before-shell' for more info.")
Operations not mentioned here will be handled by the default Emacs
primitives.")
;; Options for remote processes via winexe.
-;;;###tramp-autoload
(defcustom tramp-smb-winexe-program "winexe"
"Name of winexe client to run.
If it isn't found in the local $PATH, the absolute path of winexe
@@ -314,7 +309,6 @@ shall be given. This is needed for remote processes."
:type 'string
:version "24.3")
-;;;###tramp-autoload
(defcustom tramp-smb-winexe-shell-command "powershell.exe"
"Shell to be used for processes on remote machines.
This must be Powershell V2 compatible."
@@ -322,7 +316,6 @@ This must be Powershell V2 compatible."
:type 'string
:version "24.3")
-;;;###tramp-autoload
(defcustom tramp-smb-winexe-shell-command-switch "-file -"
"Command switch used together with `tramp-smb-winexe-shell-command'.
This can be used to disable echo etc."
diff --git a/tramp-sshfs.el b/tramp-sshfs.el
new file mode 100644
index 0000000..c4a36fe
--- /dev/null
+++ b/tramp-sshfs.el
@@ -0,0 +1,367 @@
+;;; tramp-sshfs.el --- Tramp access functions via sshfs -*- lexical-binding:t
-*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Michael Albinus <michael.albinus@gmx.de>
+;; Keywords: comm, processes
+;; Package: tramp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; sshfs is a program to mount a virtual file system, based on an sftp
+;; connection. Tramp uses its mount utility to access files and
+;; directories there.
+
+;; A remote file under sshfs control has the form
+;; "/sshfs:user@host#port:/path/to/file". User name and port number
+;; are optional.
+
+;;; Code:
+
+(require 'tramp)
+(require 'tramp-fuse)
+
+;;;###tramp-autoload
+(defconst tramp-sshfs-method "sshfs"
+ "Tramp method for sshfs mounts.")
+
+(defcustom tramp-sshfs-program "sshfs"
+ "The sshfs mount command."
+ :group 'tramp
+ :version "28.1"
+ :type 'string)
+
+;;;###tramp-autoload
+(tramp--with-startup
+ (add-to-list 'tramp-methods
+ `(,tramp-sshfs-method
+ (tramp-mount-args (("-C") ("-p" "%p")
+ ("-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-direct-async t)
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-c"))))
+
+ (add-to-list 'tramp-connection-properties
+ `(,(format "/%s:" tramp-sshfs-method) "direct-async-process" t))
+
+ (tramp-set-completion-function
+ tramp-sshfs-method tramp-completion-function-alist-ssh))
+
+
+;; New handlers should be added here.
+;;;###tramp-autoload
+(defconst tramp-sshfs-file-name-handler-alist
+ '((access-file . tramp-handle-access-file)
+ (add-name-to-file . tramp-handle-add-name-to-file)
+ ;; `byte-compiler-base-file-name' performed by default handler.
+ (copy-directory . tramp-handle-copy-directory)
+ (copy-file . tramp-sshfs-handle-copy-file)
+ (delete-directory . tramp-fuse-handle-delete-directory)
+ (delete-file . tramp-fuse-handle-delete-file)
+ ;; `diff-latest-backup-file' performed by default handler.
+ (directory-file-name . tramp-handle-directory-file-name)
+ (directory-files . tramp-fuse-handle-directory-files)
+ (directory-files-and-attributes
+ . tramp-handle-directory-files-and-attributes)
+ (dired-compress-file . ignore)
+ (dired-uncache . tramp-handle-dired-uncache)
+ (exec-path . tramp-sshfs-handle-exec-path)
+ (expand-file-name . tramp-handle-expand-file-name)
+ (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+ (file-acl . ignore)
+ (file-attributes . tramp-fuse-handle-file-attributes)
+ (file-directory-p . tramp-handle-file-directory-p)
+ (file-equal-p . tramp-handle-file-equal-p)
+ (file-executable-p . tramp-fuse-handle-file-executable-p)
+ (file-exists-p . tramp-handle-file-exists-p)
+ (file-in-directory-p . tramp-handle-file-in-directory-p)
+ (file-local-copy . tramp-handle-file-local-copy)
+ (file-modes . tramp-handle-file-modes)
+ (file-name-all-completions . tramp-fuse-handle-file-name-all-completions)
+ (file-name-as-directory . tramp-handle-file-name-as-directory)
+ (file-name-case-insensitive-p . tramp-handle-file-name-case-insensitive-p)
+ (file-name-completion . tramp-handle-file-name-completion)
+ (file-name-directory . tramp-handle-file-name-directory)
+ (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-ownership-preserved-p . ignore)
+ (file-readable-p . tramp-fuse-handle-file-readable-p)
+ (file-regular-p . tramp-handle-file-regular-p)
+ (file-remote-p . tramp-handle-file-remote-p)
+ (file-selinux-context . tramp-handle-file-selinux-context)
+ (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)
+ (find-backup-file-name . tramp-handle-find-backup-file-name)
+ ;; `get-file-buffer' performed by default handler.
+ (insert-directory . tramp-handle-insert-directory)
+ (insert-file-contents . tramp-sshfs-handle-insert-file-contents)
+ (load . tramp-handle-load)
+ (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
+ (make-directory . tramp-fuse-handle-make-directory)
+ (make-directory-internal . ignore)
+ (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
+ (make-process . tramp-handle-make-process)
+ (make-symbolic-link . tramp-handle-make-symbolic-link)
+ (process-file . tramp-sshfs-handle-process-file)
+ (rename-file . tramp-sshfs-handle-rename-file)
+ (set-file-acl . ignore)
+ (set-file-modes . tramp-sshfs-handle-set-file-modes)
+ (set-file-selinux-context . ignore)
+ (set-file-times . ignore)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
+ (shell-command . tramp-handle-shell-command)
+ (start-file-process . tramp-handle-start-file-process)
+ (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (temporary-file-directory . tramp-handle-temporary-file-directory)
+ (tramp-get-remote-gid . ignore)
+ (tramp-get-remote-uid . ignore)
+ (tramp-set-file-uid-gid . ignore)
+ (unhandled-file-name-directory . ignore)
+ (vc-registered . ignore)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-sshfs-handle-write-region))
+"Alist of handler functions for Tramp SSHFS method.
+Operations not mentioned here will be handled by the default Emacs
primitives.")
+
+;; It must be a `defsubst' in order to push the whole code into
+;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
+;;;###tramp-autoload
+(defsubst tramp-sshfs-file-name-p (filename)
+ "Check if it's a FILENAME for sshfs."
+ (and (tramp-tramp-file-p filename)
+ (string= (tramp-file-name-method (tramp-dissect-file-name filename))
+ tramp-sshfs-method)))
+
+;;;###tramp-autoload
+(defun tramp-sshfs-file-name-handler (operation &rest args)
+ "Invoke the sshfs handler for OPERATION and ARGS.
+First arg specifies the OPERATION, second arg is a list of
+arguments to pass to the OPERATION."
+ (if-let ((fn (assoc operation tramp-sshfs-file-name-handler-alist)))
+ (save-match-data (apply (cdr fn) args))
+ (tramp-run-real-handler operation args)))
+
+;;;###tramp-autoload
+(tramp--with-startup
+ (tramp-register-foreign-file-name-handler
+ #'tramp-sshfs-file-name-p #'tramp-sshfs-file-name-handler))
+
+
+;; File name primitives.
+
+(defun tramp-sshfs-handle-copy-file
+ (filename newname &optional ok-if-already-exists keep-date
+ preserve-uid-gid preserve-extended-attributes)
+ "Like `copy-file' for Tramp files."
+ (setq filename (expand-file-name filename)
+ newname (expand-file-name newname))
+ (if (file-directory-p filename)
+ (copy-directory filename newname keep-date t)
+ (copy-file
+ (if (tramp-sshfs-file-name-p filename)
+ (tramp-fuse-local-file-name filename) filename)
+ (if (tramp-sshfs-file-name-p newname)
+ (tramp-fuse-local-file-name newname) newname)
+ ok-if-already-exists keep-date
+ preserve-uid-gid preserve-extended-attributes)
+ (when (tramp-sshfs-file-name-p newname)
+ (with-parsed-tramp-file-name newname nil
+ (tramp-flush-file-properties v localname)))))
+
+(defun tramp-sshfs-handle-exec-path ()
+ "Like `exec-path' for Tramp files."
+ (append
+ (with-parsed-tramp-file-name default-directory nil
+ (with-tramp-connection-property (tramp-get-process v) "remote-path"
+ (with-temp-buffer
+ (process-file "getconf" nil t nil "PATH")
+ (split-string
+ (progn
+ ;; Read the expression.
+ (goto-char (point-min))
+ (buffer-substring (point) (point-at-eol)))
+ ":" 'omit))))
+ ;; The equivalent to `exec-directory'.
+ `(,(tramp-file-local-name (expand-file-name default-directory)))))
+
+(defun tramp-sshfs-handle-file-system-info (filename)
+ "Like `file-system-info' for Tramp files."
+ ;;`file-system-info' exists since Emacs 27.1.
+ (tramp-compat-funcall 'file-system-info (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."
+ (let ((result
+ (insert-file-contents
+ (tramp-fuse-local-file-name filename) visit beg end replace)))
+ (when visit (setq buffer-file-name filename))
+ (cons (expand-file-name filename) (cdr result))))
+
+(defun tramp-sshfs-handle-process-file
+ (program &optional infile destination display &rest args)
+ "Like `process-file' for Tramp files."
+ ;; The implementation is not complete yet.
+ (when (and (numberp destination) (zerop destination))
+ (error "Implementation does not handle immediate return"))
+
+ (with-parsed-tramp-file-name default-directory nil
+ (let ((command
+ (format
+ "cd %s && exec %s"
+ localname
+ (mapconcat #'tramp-shell-quote-argument (cons program args) " "))))
+ (unwind-protect
+ (apply
+ #'tramp-call-process
+ v (tramp-get-method-parameter v 'tramp-login-program)
+ infile destination display
+ (tramp-expand-args
+ v 'tramp-login-args
+ ?h (or (tramp-file-name-host v) "")
+ ?u (or (tramp-file-name-user v) "")
+ ?p (or (tramp-file-name-port v) "")
+ ?l command))
+
+ (unless process-file-side-effects
+ (tramp-flush-directory-properties v ""))))))
+
+(defun tramp-sshfs-handle-rename-file
+ (filename newname &optional ok-if-already-exists)
+ "Like `rename-file' for Tramp files."
+ (setq filename (expand-file-name filename)
+ newname (expand-file-name newname))
+ (rename-file
+ (if (tramp-sshfs-file-name-p filename)
+ (tramp-fuse-local-file-name filename) filename)
+ (if (tramp-sshfs-file-name-p newname)
+ (tramp-fuse-local-file-name newname) newname)
+ ok-if-already-exists)
+ (when (tramp-sshfs-file-name-p filename)
+ (with-parsed-tramp-file-name filename nil
+ (tramp-flush-file-properties v localname)))
+ (when (tramp-sshfs-file-name-p newname)
+ (with-parsed-tramp-file-name newname nil
+ (tramp-flush-file-properties v localname))))
+
+(defun tramp-sshfs-handle-set-file-modes (filename mode &optional flag)
+ "Like `set-file-modes' for Tramp files."
+ (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-modes
+ (tramp-fuse-local-file-name filename) mode flag))))
+
+(defun tramp-sshfs-handle-write-region
+ (start end filename &optional append visit lockname mustbenew)
+ "Like `write-region' for Tramp files."
+ (setq filename (expand-file-name filename))
+ (with-parsed-tramp-file-name filename nil
+ (when (and mustbenew (file-exists-p filename)
+ (or (eq mustbenew 'excl)
+ (not
+ (y-or-n-p
+ (format "File %s exists; overwrite anyway? " filename)))))
+ (tramp-error v 'file-already-exists filename))
+
+ (write-region
+ start end (tramp-fuse-local-file-name filename) append 'nomessage
lockname)
+ (tramp-flush-file-properties v localname)
+
+ ;; The end.
+ (when (and (null noninteractive)
+ (or (eq visit t) (null visit) (stringp visit)))
+ (tramp-message v 0 "Wrote %s" filename))
+ (run-hooks 'tramp-handle-write-region-hook)))
+
+
+;; File name conversions.
+
+(defun tramp-sshfs-maybe-open-connection (vec)
+ "Maybe open a connection VEC.
+Does not do anything if a connection is already open, but re-opens the
+connection if a previous connection has died for some reason."
+ ;; During completion, don't reopen a new connection.
+ (unless (tramp-connectable-p vec)
+ (throw 'non-essential 'non-essential))
+
+ ;; We need a process bound to the connection buffer. Therefore, we
+ ;; create a dummy process. Maybe there is a better solution?
+ (unless (get-buffer-process (tramp-get-connection-buffer vec))
+ (let ((p (make-network-process
+ :name (tramp-get-connection-name vec)
+ :buffer (tramp-get-connection-buffer vec)
+ :server t :host 'local :service t :noquery t)))
+ (process-put p 'vector vec)
+ (set-process-query-on-exit-flag p nil)
+
+ ;; Set connection-local variables.
+ (tramp-set-connection-local-variables vec)
+
+ ;; Create directory.
+ (unless (file-directory-p (tramp-fuse-mount-point vec))
+ (make-directory (tramp-fuse-mount-point vec) 'parents))
+
+ (unless
+ (or (tramp-fuse-mounted-p vec)
+ (with-temp-buffer
+ (zerop
+ (apply
+ #'tramp-call-process
+ vec tramp-sshfs-program nil t nil
+ (tramp-fuse-mount-spec vec)
+ (tramp-fuse-mount-point vec)
+ (tramp-expand-args
+ vec 'tramp-mount-args
+ ?p (or (tramp-file-name-port vec) "")))))
+ (tramp-error
+ vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec))))
+
+ ;; Mark it as connected.
+ (tramp-set-connection-property
+ (tramp-get-connection-process vec) "connected" t)))
+
+ ;; In `tramp-check-cached-permissions', the connection properties
+ ;; "{uid,gid}-{integer,string}" are used. We set them to proper values.
+ (with-tramp-connection-property
+ vec "uid-integer" (tramp-get-local-uid 'integer))
+ (with-tramp-connection-property
+ vec "gid-integer" (tramp-get-local-gid 'integer))
+ (with-tramp-connection-property
+ vec "uid-string" (tramp-get-local-uid 'string))
+ (with-tramp-connection-property
+ vec "gid-string" (tramp-get-local-gid 'string)))
+
+(add-hook 'tramp-unload-hook
+ (lambda ()
+ (unload-feature 'tramp-sshfs 'force)))
+
+(provide 'tramp-sshfs)
+
+;;; tramp-sshfs.el ends here
diff --git a/tramp-sudoedit.el b/tramp-sudoedit.el
index e181365..66737e6 100644
--- a/tramp-sudoedit.el
+++ b/tramp-sudoedit.el
@@ -791,22 +791,16 @@ in case of error, t otherwise."
(tramp-sudoedit-maybe-open-connection vec)
(with-current-buffer (tramp-get-connection-buffer vec)
(erase-buffer)
- (let* ((login (tramp-get-method-parameter vec 'tramp-sudo-login))
- (host (or (tramp-file-name-host vec) ""))
- (user (or (tramp-file-name-user vec) ""))
- (spec (format-spec-make ?h host ?u user))
- (args (append
- (tramp-compat-flatten-tree
- (mapcar
- (lambda (x)
- (setq x (mapcar (lambda (y) (format-spec y spec)) x))
- (unless (member "" x) x))
- login))
- (tramp-compat-flatten-tree (delq nil args))))
- (delete-exited-processes t)
+ (let* ((delete-exited-processes t)
(process-connection-type tramp-process-connection-type)
(p (apply #'start-process
- (tramp-get-connection-name vec) (current-buffer) args))
+ (tramp-get-connection-name vec) (current-buffer)
+ (append
+ (tramp-expand-args
+ vec 'tramp-sudo-login
+ ?h (or (tramp-file-name-host vec) "")
+ ?u (or (tramp-file-name-user vec) ""))
+ (tramp-compat-flatten-tree args))))
;; We suppress the messages `Waiting for prompts from remote shell'.
(tramp-verbose (if (= tramp-verbose 3) 2 tramp-verbose))
;; We do not want to save the password.
diff --git a/tramp.el b/tramp.el
index 1ba5bcc..f509afc 100644
--- a/tramp.el
+++ b/tramp.el
@@ -386,6 +386,8 @@ Also see `tramp-default-method-alist'."
:type 'string)
(defcustom tramp-default-method-alist nil
+ ;; FIXME: This is not an "alist", because its elements are not of
+ ;; the form (KEY . VAL) but (KEY1 KEY2 VAL).
"Default method to use for specific host/user pairs.
This is an alist of items (HOST USER METHOD). The first matching item
specifies the method to use for a file name which does not specify a
@@ -413,6 +415,8 @@ This variable is regarded as obsolete, and will be removed
soon."
:type '(choice (const nil) string))
(defcustom tramp-default-user-alist nil
+ ;; FIXME: This is not an "alist", because its elements are not of
+ ;; the form (KEY . VAL) but (KEY1 KEY2 VAL).
"Default user to use for specific method/host pairs.
This is an alist of items (METHOD HOST USER). The first matching item
specifies the user to use for a file name which does not specify a
@@ -432,6 +436,8 @@ Useful for su and sudo methods mostly."
:type 'string)
(defcustom tramp-default-host-alist nil
+ ;; FIXME: This is not an "alist", because its elements are not of
+ ;; the form (KEY . VAL) but (KEY1 KEY2 VAL).
"Default host to use for specific method/user pairs.
This is an alist of items (METHOD USER HOST). The first matching item
specifies the host to use for a file name which does not specify a
@@ -447,6 +453,8 @@ empty string for the method name."
(choice :tag " Host name" string (const nil)))))
(defcustom tramp-default-proxies-alist nil
+ ;; FIXME: This is not an "alist", because its elements are not of
+ ;; the form (KEY . VAL) but (KEY1 KEY2 VAL).
"Route to be followed for specific host/user pairs.
This is an alist of items (HOST USER PROXY). The first matching
item specifies the proxy to be passed for a file name located on
@@ -652,6 +660,14 @@ The regexp should match at end of buffer.
See also `tramp-yesno-prompt-regexp'."
:type 'regexp)
+(defcustom tramp-terminal-type "dumb"
+ "Value of TERM environment variable for logging in to remote host.
+Because Tramp wants to parse the output of the remote shell, it is easily
+confused by ANSI color escape sequences and suchlike. Often, shell init
+files conditionalize this setup based on the TERM environment variable."
+ :group 'tramp
+ :type 'string)
+
(defcustom tramp-terminal-prompt-regexp
(concat "\\("
"TERM = (.*)"
@@ -1235,6 +1251,67 @@ let-bind this variable."
:version "24.4"
:type '(choice (const nil) integer))
+;; "getconf PATH" yields:
+;; HP-UX:
/usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
+;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
+;; GNU/Linux (Debian, Suse, RHEL): /bin:/usr/bin
+;; FreeBSD, DragonFly: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
+;; FreeBSD 12.1, Darwin: /usr/bin:/bin:/usr/sbin:/sbin
+;; IRIX64: /usr/bin
+;; QNAP QTS: ---
+;; Hydra: /run/current-system/sw/bin:/bin:/usr/bin
+(defcustom tramp-remote-path
+ '(tramp-default-remote-path "/bin" "/usr/bin" "/sbin" "/usr/sbin"
+ "/usr/local/bin" "/usr/local/sbin" "/local/bin" "/local/freeware/bin"
+ "/local/gnu/bin" "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin"
+ "/opt/bin" "/opt/sbin" "/opt/local/bin")
+ "List of directories to search for executables on remote host.
+For every remote host, this variable will be set buffer local,
+keeping the list of existing directories on that host.
+
+You can use \"~\" in this list, but when searching for a shell which groks
+tilde expansion, all directory names starting with \"~\" will be ignored.
+
+`Default Directories' represent the list of directories given by
+the command \"getconf PATH\". It is recommended to use this
+entry on head of this list, because these are the default
+directories for POSIX compatible commands. On remote hosts which
+do not offer the getconf command (like cygwin), the value
+\"/bin:/usr/bin\" is used instead. This entry is represented in
+the list by the special value `tramp-default-remote-path'.
+
+`Private Directories' are the settings of the $PATH environment,
+as given in your `~/.profile'. This entry is represented in
+the list by the special value `tramp-own-remote-path'."
+ :group 'tramp
+ :type '(repeat (choice
+ (const :tag "Default Directories" tramp-default-remote-path)
+ (const :tag "Private Directories" tramp-own-remote-path)
+ (string :tag "Directory"))))
+
+(defcustom tramp-remote-process-environment
+ '("ENV=''" "TMOUT=0" "LC_CTYPE=''"
+ "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat"
+ "autocorrect=" "correct=")
+ "List of environment variables to be set on the remote host.
+
+Each element should be a string of the form ENVVARNAME=VALUE. An
+entry ENVVARNAME= disables the corresponding environment variable,
+which might have been set in the init files like ~/.profile.
+
+Special handling is applied to some environment variables,
+which should not be set here:
+
+The PATH environment variable should be set via `tramp-remote-path'.
+
+The TERM environment variable should be set via `tramp-terminal-type'.
+
+The INSIDE_EMACS environment variable will automatically be set
+based on the Tramp and Emacs versions, and should not be set here."
+ :group 'tramp
+ :version "26.1"
+ :type '(repeat string))
+
(defcustom tramp-completion-reread-directory-timeout 10
"Defines seconds since last remote command before rereading a directory.
A remote directory might have changed its contents. In order to
@@ -1710,6 +1787,10 @@ version, the function does nothing."
"Used for highlighting Tramp debug buffers in `outline-mode'.")
(defconst tramp-debug-font-lock-keywords
+ ;; FIXME: Make it a function instead of an ELisp expression, so you
+ ;; can evaluate it with `funcall' rather than `eval'!
+ ;; Also, in `font-lock-defaults' you can specify a function name for
+ ;; the "KEYWORDS" part, so font-lock calls it to get the actual keywords!
'(list
(concat "^\\(?:" tramp-debug-outline-regexp "\\).+")
'(1 font-lock-warning-face t t)
@@ -1738,8 +1819,11 @@ The outline level is equal to the verbosity of the Tramp
message."
(outline-mode))
(setq-local outline-level 'tramp-debug-outline-level)
(setq-local font-lock-keywords
- `(t (eval ,tramp-debug-font-lock-keywords)
- ,(eval tramp-debug-font-lock-keywords)))
+ ;; FIXME: This `(t FOO . BAR)' representation in
+ ;; `font-lock-keywords' is supposed to be an
+ ;; internal implementation "detail". Don't abuse it here!
+ `(t (eval ,tramp-debug-font-lock-keywords t)
+ ,(eval tramp-debug-font-lock-keywords t)))
;; Do not edit the debug buffer.
(use-local-map special-mode-map))
(current-buffer)))
@@ -2625,6 +2709,14 @@ Add operations defined in `HANDLER-alist' to
`tramp-file-name-handler'."
;;; File name handler functions for completion mode:
+;; This function takes action since Emacs 28.1, when
+;; `read-extended-command-predicate' is set to
+;; `command-completion-default-include-p'.
+(defun tramp-command-completion-p (_symbol buffer)
+ "A predicate for Tramp interactive commands.
+They are completed by \"M-x TAB\" only if the current buffer is remote."
+ (with-current-buffer buffer (tramp-tramp-file-p default-directory)))
+
(defun tramp-connectable-p (vec-or-filename)
"Check, whether it is possible to connect the remote host w/o side-effects.
This is true, if either the remote host is already connected, or if we are
@@ -3717,15 +3809,15 @@ User is always nil."
(setq choices tramp-default-proxies-alist)
(while choices
(setq item (pop choices)
- proxy (eval (nth 2 item)))
+ proxy (eval (nth 2 item) t))
(when (and
;; Host.
(string-match-p
- (or (eval (nth 0 item)) "")
+ (or (eval (nth 0 item) t) "")
(or (tramp-file-name-host-port (car target-alist)) ""))
;; User.
(string-match-p
- (or (eval (nth 1 item)) "")
+ (or (eval (nth 1 item) t) "")
(or (tramp-file-name-user-domain (car target-alist)) "")))
(if (null proxy)
;; No more hops needed.
@@ -3776,6 +3868,22 @@ User is always nil."
;; Result.
target-alist))
+(defun tramp-expand-args (vec parameter &rest spec-list)
+ "Expand login arguments as given by PARAMETER in `tramp-methods'.
+PARAMETER is a symbol like `tramp-login-args', denoting a list of
+list of strings from `tramp-methods', containing %-sequences for
+substitution. SPEC-LIST is a list of char/value pairs used for
+`format-spec-make'."
+ (let ((args (tramp-get-method-parameter vec parameter))
+ (spec (apply 'format-spec-make spec-list)))
+ ;; Expand format spec.
+ (tramp-compat-flatten-tree
+ (mapcar
+ (lambda (x)
+ (setq x (mapcar (lambda (y) (format-spec y spec)) x))
+ (unless (member "" x) x))
+ args))))
+
(defun tramp-direct-async-process-p (&rest args)
"Whether direct async `make-process' can be called."
(let ((v (tramp-dissect-file-name default-directory))
@@ -3857,14 +3965,11 @@ It does not support `:stderr'."
(append `("cd" ,localname "&&" "(" "env") env `(,command ")"))))
;; Check for `tramp-sh-file-name-handler', because something
- ;; is different between tramp-adb.el and tramp-sh.el.
+ ;; 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))
(login-program
(tramp-get-method-parameter v 'tramp-login-program))
- (login-args
- (tramp-get-method-parameter v 'tramp-login-args))
- (async-args
- (tramp-get-method-parameter v 'tramp-async-args))
;; 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
@@ -3882,29 +3987,23 @@ It does not support `:stderr'."
(when sh-file-name-handler-p
(tramp-compat-funcall
'tramp-ssh-controlmaster-options v)))
- spec p)
+ login-args p)
- ;; Replace `login-args' place holders.
+ ;; Replace `login-args' place holders. Split
+ ;; ControlMaster options.
(setq
- spec (format-spec-make ?t tmpfile)
- options (format-spec (or options "") spec)
- spec (format-spec-make
- ?h (or host "") ?u (or user "") ?p (or port "")
- ?c options ?l "")
- ;; Add arguments for asynchronous processes.
- login-args (append async-args login-args)
- ;; Expand format spec.
- login-args
- (tramp-compat-flatten-tree
- (mapcar
- (lambda (x)
- (setq x (mapcar (lambda (y) (format-spec y spec)) x))
- (unless (member "" x) x))
- login-args))
- ;; Split ControlMaster options.
login-args
- (tramp-compat-flatten-tree
- (mapcar (lambda (x) (split-string x " ")) login-args))
+ (append
+ (tramp-compat-flatten-tree
+ (tramp-get-method-parameter v 'tramp-async-args))
+ (tramp-compat-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))
+ ?l ""))))
p (make-process
:name name :buffer buffer
:command (append `(,login-program) login-args command)
@@ -5473,11 +5572,6 @@ BODY is the backend specific code."
;; strange when doing zerop, we should kill the process and start
;; again. (Greg Stark)
;;
-;; * I was wondering if it would be possible to use tramp even if I'm
-;; actually using sshfs. But when I launch a command I would like
-;; to get it executed on the remote machine where the files really
-;; are. (Andrea Crotti)
-;;
;; * Run emerge on two remote files. Bug is described here:
;; <https://www.mail-archive.com/tramp-devel@nongnu.org/msg01041.html>.
;; (Bug#6850)
diff --git a/trampver.el b/trampver.el
index c151892..34032c0 100644
--- a/trampver.el
+++ b/trampver.el
@@ -7,7 +7,7 @@
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
;; Keywords: comm, processes
;; Package: tramp
-;; Version: 2.5.0.2
+;; Version: 2.5.0.3
;; 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.0.2"
+(defconst tramp-version "2.5.0.3"
"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.0.2 is not fit for %s"
+ (format "Tramp 2.5.0.3 is not fit for %s"
(replace-regexp-in-string "\n" "" (emacs-version))))))
(unless (string-equal "ok" x) (error "%s" x)))