diff options
| author | Michael Albinus | 2022-08-03 17:30:09 +0200 |
|---|---|---|
| committer | Michael Albinus | 2022-08-03 17:30:09 +0200 |
| commit | 21afc26d4df6bae35ba032d4b6b03fb7fb2bf1b3 (patch) | |
| tree | d9144d4fc404365fcdc431293d8358a067a909b5 | |
| parent | 3ec6b806b246c147ae30408a1d659083619883af (diff) | |
| download | emacs-21afc26d4df6bae35ba032d4b6b03fb7fb2bf1b3.tar.gz emacs-21afc26d4df6bae35ba032d4b6b03fb7fb2bf1b3.zip | |
Reorganize Tramp
* lisp/net/tramp-adb.el (tramp-adb-handle-write-region): Handle special
case that START is "".
(tramp-adb-handle-set-file-modes)
(tramp-adb-handle-set-file-times):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
(tramp-adb-handle-make-process):
Use `with-tramp-saved-connection-properties'.
* lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
Use `tramp-archive-handle-file-exists-p'.
(tramp-archive-handle-file-exists-p): New defun.
(tramp-archive-file-name-handler): Add ;;;###tramp-autoload cookie.
* lisp/net/tramp-cache.el (tramp-compat, tramp-loaddefs)
(time-stamp): Require.
(tramp-get-file-property, tramp-set-file-property)
(tramp-flush-file-property, tramp-flush-file-upper-properties)
(tramp-flush-file-properties): Use `tramp-file-name-unify'. Adapt
message.
(tramp-flush-directory-properties): Simplify.
(tramp-flush-file-function): Add ;;;###tramp-autoload cookie.
Don't use `with-parsed-tramp-file-name', it isn't exposed.
(with-tramp-file-property, with-tramp-connection-property)
(with-tramp-saved-connection-property): Macros moved from tramp.el.
(with-tramp-saved-file-property)
(with-tramp-saved-file-properties)
(with-tramp-saved-connection-properties): New defmacros.
* lisp/net/tramp-cmds.el (tramp-cleanup-connection): Flush "/".
* lisp/net/tramp-crypt.el (tramp-crypt-handle-set-file-modes)
(tramp-crypt-handle-set-file-times)
(tramp-crypt-handle-set-file-uid-gid):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
* lisp/net/tramp-ftp.el (tramp-archive-file-name-handler):
Don't declare.
* lisp/net/tramp-gvfs.el (tramp-gvfs-info): New defun.
(tramp-gvfs-do-copy-or-rename-file)
(tramp-gvfs-handle-delete-directory)
(tramp-gvfs-handle-delete-file, tramp-gvfs-get-root-attributes)
(tramp-gvfs-handle-make-directory): Use it.
(tramp-gvfs-handle-set-file-modes)
(tramp-gvfs-handle-set-file-times)
(tramp-gvfs-handle-set-file-uid-gid):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
* lisp/net/tramp-sh.el (tramp-sh-handle-make-symbolic-link):
Expand TARGET when flushing file properties.
(tramp-sh-handle-set-file-modes, tramp-sh-handle-set-file-times)
(tramp-sh-handle-set-file-uid-gid):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
(tramp-sh-handle-file-name-all-completions): Protect, when
connection is not established yet.
(tramp-do-copy-or-rename-file-directly): Flush file properties of
NEWNAME when constructing a new remote file name.
(tramp-do-copy-or-rename-file-out-of-band, tramp-sh-handle-make-process):
Use `with-tramp-saved-connection-properties'.
(tramp-sh-handle-delete-file): Flush file properties only after
deleting, otherwise we get a false alarm.
(tramp-sh-handle-process-file): Flush "/".
(tramp-sh-handle-write-region): Handle special case that START is "".
* lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
(tramp-smb-handle-file-acl, tramp-smb-handle-process-file)
(tramp-smb-handle-set-file-acl)
(tramp-smb-handle-start-file-process):
Use `with-tramp-saved-connection-properties'.
(tramp-smb-remote-acl-p): New defun.
(tramp-smb-handle-file-acl, tramp-smb-handle-set-file-acl): Use it.
(tramp-smb-handle-set-file-modes):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
(tramp-smb-handle-process-file, tramp-smb-maybe-open-connection):
Flush "/".
* lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file): Flush "/".
(tramp-sshfs-handle-set-file-modes)
(tramp-sshfs-handle-set-file-times):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes)
(tramp-sudoedit-handle-set-file-times)
(tramp-sudoedit-handle-set-file-uid-gid):
Use `tramp-skeleton-set-file-modes-times-uid-gid'.
* lisp/net/tramp.el (tramp-archive-file-name-handler): Don't declare.
(tramp-verbose, tramp-file-name-unify, tramp-tramp-file-p)
(tramp-file-local-name, tramp-dissect-file-name)
(tramp-make-tramp-file-name, tramp-get-connection-buffer)
(tramp-get-buffer-string, tramp-debug-message)
(tramp-inhibit-progress-reporter, tramp-message):
Add ;;;###tramp-autoload cookie.
(tramp-file-name): Expose defstruct to tramp-loaddefs.el
(tramp-file-name-unify): New optional arg FILE.
(tramp-get-default-directory, tramp-get-buffer-string)
(tramp-message, tramp-backtrace, tramp-error-with-buffer)
(tramp-with-demoted-errors, tramp-barf-if-file-missing)
(tramp-skeleton-copy-directory, tramp-skeleton-delete-directory)
(tramp-skeleton-directory-files)
(tramp-skeleton-directory-files-and-attributes)
(tramp-skeleton-file-local-copy, tramp-skeleton-write-region):
Remove `tramp-suppress-trace' property, it isn't needed for
defmacros and defsubsts.
(with-tramp-file-property, with-tramp-connection-property)
(with-tramp-saved-connection-property): Move macros to tramp-cache.el.
(tramp-skeleton-directory-files-and-attributes): Fix implementation.
(tramp-skeleton-file-local-copy): Fix docstring.
(tramp-skeleton-set-file-modes-times-uid-gid): New defmacro.
(tramp-skeleton-write-region): Set "file-exists-p" cache property.
(tramp-handle-file-exists-p): Use cached value.
(tramp-process-sentinel): Flush "/".
(tramp-make-tramp-temp-file): Suppress also `tramp-smb-remote-acl-p'.
(tramp-get-connection-buffer):
* test/lisp/net/tramp-tests.el (tramp-test10-write-region)
(tramp-test20-file-modes, tramp-test22-file-times): Extend tests.
| -rw-r--r-- | lisp/net/tramp-adb.el | 236 | ||||
| -rw-r--r-- | lisp/net/tramp-archive.el | 12 | ||||
| -rw-r--r-- | lisp/net/tramp-cache.el | 164 | ||||
| -rw-r--r-- | lisp/net/tramp-cmds.el | 2 | ||||
| -rw-r--r-- | lisp/net/tramp-crypt.el | 9 | ||||
| -rw-r--r-- | lisp/net/tramp-ftp.el | 1 | ||||
| -rw-r--r-- | lisp/net/tramp-gvfs.el | 47 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 701 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 346 | ||||
| -rw-r--r-- | lisp/net/tramp-sshfs.el | 13 | ||||
| -rw-r--r-- | lisp/net/tramp-sudoedit.el | 24 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 127 | ||||
| -rw-r--r-- | test/lisp/net/tramp-tests.el | 23 |
13 files changed, 905 insertions, 800 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 3e780aa1a18..1d35f2b2ff7 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el | |||
| @@ -517,34 +517,39 @@ Emacs dired can't find files." | |||
| 517 | (start end filename &optional append visit lockname mustbenew) | 517 | (start end filename &optional append visit lockname mustbenew) |
| 518 | "Like `write-region' for Tramp files." | 518 | "Like `write-region' for Tramp files." |
| 519 | (tramp-skeleton-write-region start end filename append visit lockname mustbenew | 519 | (tramp-skeleton-write-region start end filename append visit lockname mustbenew |
| 520 | (let ((tmpfile (tramp-compat-make-temp-file filename))) | 520 | ;; If `start' is the empty string, it is likely that a temporary |
| 521 | (when (and append (file-exists-p filename)) | 521 | ;; file is created. Do it directly. |
| 522 | (copy-file filename tmpfile 'ok) | 522 | (if (and (stringp start) (string-empty-p start)) |
| 523 | (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600))) | 523 | (tramp-adb-send-command-and-check |
| 524 | (let (create-lockfiles) | 524 | v (format "echo -n \"\">%s" (tramp-shell-quote-argument localname))) |
| 525 | (write-region start end tmpfile append 'no-message)) | 525 | |
| 526 | (with-tramp-progress-reporter | 526 | (let ((tmpfile (tramp-compat-make-temp-file filename))) |
| 527 | v 3 (format-message | 527 | (when (and append (file-exists-p filename)) |
| 528 | "Moving tmp file `%s' to `%s'" tmpfile filename) | 528 | (copy-file filename tmpfile 'ok) |
| 529 | (unwind-protect | 529 | (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600))) |
| 530 | (unless (tramp-adb-execute-adb-command | 530 | (let (create-lockfiles) |
| 531 | v "push" tmpfile (tramp-compat-file-name-unquote localname)) | 531 | (write-region start end tmpfile append 'no-message)) |
| 532 | (tramp-error v 'file-error "Cannot write: `%s'" filename)) | 532 | (with-tramp-progress-reporter |
| 533 | (delete-file tmpfile)))))) | 533 | v 3 (format-message |
| 534 | "Moving tmp file `%s' to `%s'" tmpfile filename) | ||
| 535 | (unwind-protect | ||
| 536 | (unless (tramp-adb-execute-adb-command | ||
| 537 | v "push" tmpfile | ||
| 538 | (tramp-compat-file-name-unquote localname)) | ||
| 539 | (tramp-error v 'file-error "Cannot write: `%s'" filename)) | ||
| 540 | (delete-file tmpfile))))))) | ||
| 534 | 541 | ||
| 535 | (defun tramp-adb-handle-set-file-modes (filename mode &optional flag) | 542 | (defun tramp-adb-handle-set-file-modes (filename mode &optional flag) |
| 536 | "Like `set-file-modes' for Tramp files." | 543 | "Like `set-file-modes' for Tramp files." |
| 537 | (with-parsed-tramp-file-name filename nil | 544 | ;; ADB shell does not support "chmod -h". |
| 538 | ;; ADB shell does not support "chmod -h". | 545 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) |
| 539 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) | 546 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 540 | (tramp-flush-file-properties v localname) | ||
| 541 | (tramp-adb-send-command-and-check | 547 | (tramp-adb-send-command-and-check |
| 542 | v (format "chmod %o %s" mode (tramp-shell-quote-argument localname)))))) | 548 | v (format "chmod %o %s" mode (tramp-shell-quote-argument localname)))))) |
| 543 | 549 | ||
| 544 | (defun tramp-adb-handle-set-file-times (filename &optional time flag) | 550 | (defun tramp-adb-handle-set-file-times (filename &optional time flag) |
| 545 | "Like `set-file-times' for Tramp files." | 551 | "Like `set-file-times' for Tramp files." |
| 546 | (with-parsed-tramp-file-name filename nil | 552 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 547 | (tramp-flush-file-properties v localname) | ||
| 548 | (let ((time (if (or (null time) | 553 | (let ((time (if (or (null time) |
| 549 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) | 554 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) |
| 550 | (tramp-compat-time-equal-p time tramp-time-dont-know)) | 555 | (tramp-compat-time-equal-p time tramp-time-dont-know)) |
| @@ -827,7 +832,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 827 | ;; because the remote process could have changed them. | 832 | ;; because the remote process could have changed them. |
| 828 | (when tmpinput (delete-file tmpinput)) | 833 | (when tmpinput (delete-file tmpinput)) |
| 829 | (when process-file-side-effects | 834 | (when process-file-side-effects |
| 830 | (tramp-flush-directory-properties v "")) | 835 | (tramp-flush-directory-properties v "/")) |
| 831 | 836 | ||
| 832 | ;; Return exit status. | 837 | ;; Return exit status. |
| 833 | (if (equal ret -1) | 838 | (if (equal ret -1) |
| @@ -923,102 +928,99 @@ implementation will be used." | |||
| 923 | name1 (format "%s<%d>" name i))) | 928 | name1 (format "%s<%d>" name i))) |
| 924 | (setq name name1) | 929 | (setq name name1) |
| 925 | 930 | ||
| 926 | (with-tramp-saved-connection-property v "process-name" | 931 | (with-tramp-saved-connection-properties |
| 927 | (with-tramp-saved-connection-property v "process-buffer" | 932 | v '("process-name" "process-buffer") |
| 928 | ;; Set the new process properties. | 933 | ;; Set the new process properties. |
| 929 | (tramp-set-connection-property v "process-name" name) | 934 | (tramp-set-connection-property v "process-name" name) |
| 930 | (tramp-set-connection-property v "process-buffer" buffer) | 935 | (tramp-set-connection-property v "process-buffer" buffer) |
| 931 | (with-current-buffer (tramp-get-connection-buffer v) | 936 | (with-current-buffer (tramp-get-connection-buffer v) |
| 932 | (unwind-protect | 937 | (unwind-protect |
| 933 | ;; We catch this event. Otherwise, | 938 | ;; We catch this event. Otherwise, `make-process' |
| 934 | ;; `make-process' could be called on the local | 939 | ;; could be called on the local host. |
| 935 | ;; host. | 940 | (save-excursion |
| 936 | (save-excursion | 941 | (save-restriction |
| 937 | (save-restriction | 942 | ;; Activate narrowing in order to save BUFFER |
| 938 | ;; Activate narrowing in order to save | 943 | ;; contents. Clear also the modification |
| 939 | ;; BUFFER contents. Clear also the | 944 | ;; time; otherwise we might be interrupted by |
| 940 | ;; modification time; otherwise we might be | 945 | ;; `verify-visited-file-modtime'. |
| 941 | ;; interrupted by `verify-visited-file-modtime'. | 946 | (let ((buffer-undo-list t) |
| 942 | (let ((buffer-undo-list t) | 947 | (inhibit-read-only t) |
| 943 | (inhibit-read-only t) | 948 | (coding-system-for-write |
| 944 | (coding-system-for-write | 949 | (if (symbolp coding) coding (car coding))) |
| 945 | (if (symbolp coding) coding (car coding))) | 950 | (coding-system-for-read |
| 946 | (coding-system-for-read | 951 | (if (symbolp coding) coding (cdr coding)))) |
| 947 | (if (symbolp coding) coding (cdr coding)))) | 952 | (clear-visited-file-modtime) |
| 948 | (clear-visited-file-modtime) | 953 | (narrow-to-region (point-max) (point-max)) |
| 949 | (narrow-to-region (point-max) (point-max)) | 954 | ;; We call `tramp-adb-maybe-open-connection', |
| 950 | ;; We call `tramp-adb-maybe-open-connection', | 955 | ;; in order to cleanup the prompt afterwards. |
| 951 | ;; in order to cleanup the prompt afterwards. | 956 | (tramp-adb-maybe-open-connection v) |
| 952 | (tramp-adb-maybe-open-connection v) | 957 | (delete-region (point-min) (point-max)) |
| 953 | (delete-region (point-min) (point-max)) | 958 | ;; Send the command. |
| 954 | ;; Send the command. | 959 | (setq p (tramp-get-connection-process v)) |
| 955 | (setq p (tramp-get-connection-process v)) | 960 | (tramp-adb-send-command v command nil t) ; nooutput |
| 956 | (tramp-adb-send-command v command nil t) ; nooutput | 961 | ;; Set sentinel and filter. |
| 957 | ;; Set sentinel and filter. | 962 | (when sentinel |
| 958 | (when sentinel | 963 | (set-process-sentinel p sentinel)) |
| 959 | (set-process-sentinel p sentinel)) | 964 | (when filter |
| 960 | (when filter | 965 | (set-process-filter p filter)) |
| 961 | (set-process-filter p filter)) | 966 | (process-put p 'remote-command orig-command) |
| 962 | (process-put p 'remote-command orig-command) | 967 | (tramp-set-connection-property |
| 963 | (tramp-set-connection-property | 968 | p "remote-command" orig-command) |
| 964 | p "remote-command" orig-command) | 969 | ;; Set query flag and process marker for |
| 965 | ;; Set query flag and process marker for | 970 | ;; this process. We ignore errors, because |
| 966 | ;; this process. We ignore errors, | 971 | ;; the process could have finished already. |
| 967 | ;; because the process could have finished | 972 | (ignore-errors |
| 968 | ;; already. | 973 | (set-process-query-on-exit-flag p (null noquery)) |
| 969 | (ignore-errors | 974 | (set-marker (process-mark p) (point)) |
| 970 | (set-process-query-on-exit-flag p (null noquery)) | 975 | ;; We must flush them here already; |
| 971 | (set-marker (process-mark p) (point)) | 976 | ;; otherwise `rename-file', `delete-file' |
| 972 | ;; We must flush them here already; | 977 | ;; or `insert-file-contents' will fail. |
| 973 | ;; otherwise `rename-file', `delete-file' or | 978 | (tramp-flush-connection-property v "process-name") |
| 974 | ;; `insert-file-contents' will fail. | 979 | (tramp-flush-connection-property |
| 975 | (tramp-flush-connection-property v "process-name") | 980 | v "process-buffer") |
| 976 | (tramp-flush-connection-property | 981 | ;; Copy tmpstderr file. |
| 977 | v "process-buffer") | 982 | (when (and (stringp stderr) |
| 978 | ;; Copy tmpstderr file. | 983 | (not (tramp-tramp-file-p stderr))) |
| 979 | (when (and (stringp stderr) | 984 | (add-function |
| 980 | (not (tramp-tramp-file-p stderr))) | 985 | :after (process-sentinel p) |
| 981 | (add-function | 986 | (lambda (_proc _msg) |
| 982 | :after (process-sentinel p) | 987 | (rename-file remote-tmpstderr stderr)))) |
| 983 | (lambda (_proc _msg) | 988 | ;; Read initial output. Remove the first |
| 984 | (rename-file remote-tmpstderr stderr)))) | 989 | ;; line, which is the command echo. |
| 985 | ;; Read initial output. Remove the | 990 | (unless (eq filter t) |
| 986 | ;; first line, which is the command | 991 | (while |
| 987 | ;; echo. | 992 | (progn |
| 988 | (unless (eq filter t) | 993 | (goto-char (point-min)) |
| 989 | (while | 994 | (not (re-search-forward "[\n]" nil t))) |
| 990 | (progn | 995 | (tramp-accept-process-output p 0)) |
| 991 | (goto-char (point-min)) | 996 | (delete-region (point-min) (point))) |
| 992 | (not (re-search-forward "[\n]" nil t))) | 997 | ;; Provide error buffer. This shows only |
| 993 | (tramp-accept-process-output p 0)) | 998 | ;; initial error messages; messages |
| 994 | (delete-region (point-min) (point))) | 999 | ;; arriving later on will be inserted when |
| 995 | ;; Provide error buffer. This shows | 1000 | ;; the process is deleted. The temporary |
| 996 | ;; only initial error messages; messages | 1001 | ;; file will exist until the process is |
| 997 | ;; arriving later on will be inserted | 1002 | ;; deleted. |
| 998 | ;; when the process is deleted. The | 1003 | (when (bufferp stderr) |
| 999 | ;; temporary file will exist until the | 1004 | (with-current-buffer stderr |
| 1000 | ;; process is deleted. | 1005 | (insert-file-contents-literally |
| 1001 | (when (bufferp stderr) | 1006 | remote-tmpstderr 'visit)) |
| 1002 | (with-current-buffer stderr | 1007 | ;; Delete tmpstderr file. |
| 1003 | (insert-file-contents-literally | 1008 | (add-function |
| 1004 | remote-tmpstderr 'visit)) | 1009 | :after (process-sentinel p) |
| 1005 | ;; Delete tmpstderr file. | 1010 | (lambda (_proc _msg) |
| 1006 | (add-function | 1011 | (with-current-buffer stderr |
| 1007 | :after (process-sentinel p) | 1012 | (insert-file-contents-literally |
| 1008 | (lambda (_proc _msg) | 1013 | remote-tmpstderr 'visit nil nil 'replace)) |
| 1009 | (with-current-buffer stderr | 1014 | (delete-file remote-tmpstderr)))) |
| 1010 | (insert-file-contents-literally | 1015 | ;; Return process. |
| 1011 | remote-tmpstderr 'visit nil nil 'replace)) | 1016 | p)))) |
| 1012 | (delete-file remote-tmpstderr)))) | 1017 | |
| 1013 | ;; Return process. | 1018 | ;; Save exit. |
| 1014 | p)))) | 1019 | (if (string-prefix-p tramp-temp-buffer-name (buffer-name)) |
| 1015 | 1020 | (ignore-errors | |
| 1016 | ;; Save exit. | 1021 | (set-process-buffer p nil) |
| 1017 | (if (string-prefix-p tramp-temp-buffer-name (buffer-name)) | 1022 | (kill-buffer (current-buffer))) |
| 1018 | (ignore-errors | 1023 | (set-buffer-modified-p bmp))))))))))) |
| 1019 | (set-process-buffer p nil) | ||
| 1020 | (kill-buffer (current-buffer))) | ||
| 1021 | (set-buffer-modified-p bmp)))))))))))) | ||
| 1022 | 1024 | ||
| 1023 | (defun tramp-adb-handle-exec-path () | 1025 | (defun tramp-adb-handle-exec-path () |
| 1024 | "Like `exec-path' for Tramp files." | 1026 | "Like `exec-path' for Tramp files." |
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index b2244941102..fda1441615e 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el | |||
| @@ -240,7 +240,7 @@ It must be supported by libarchive(3).") | |||
| 240 | (file-directory-p . tramp-handle-file-directory-p) | 240 | (file-directory-p . tramp-handle-file-directory-p) |
| 241 | (file-equal-p . tramp-handle-file-equal-p) | 241 | (file-equal-p . tramp-handle-file-equal-p) |
| 242 | (file-executable-p . tramp-archive-handle-file-executable-p) | 242 | (file-executable-p . tramp-archive-handle-file-executable-p) |
| 243 | (file-exists-p . tramp-handle-file-exists-p) | 243 | (file-exists-p . tramp-archive-handle-file-exists-p) |
| 244 | (file-in-directory-p . tramp-handle-file-in-directory-p) | 244 | (file-in-directory-p . tramp-handle-file-in-directory-p) |
| 245 | (file-local-copy . tramp-archive-handle-file-local-copy) | 245 | (file-local-copy . tramp-archive-handle-file-local-copy) |
| 246 | (file-locked-p . ignore) | 246 | (file-locked-p . ignore) |
| @@ -322,7 +322,11 @@ arguments to pass to the OPERATION." | |||
| 322 | (inhibit-file-name-operation operation)) | 322 | (inhibit-file-name-operation operation)) |
| 323 | (apply operation args)))) | 323 | (apply operation args)))) |
| 324 | 324 | ||
| 325 | ;;;###autoload | 325 | ;; Starting with Emacs 29, `tramp-archive-file-name-handler' is |
| 326 | ;; autoloaded. But it must still be in tramp-loaddefs.el for older | ||
| 327 | ;; Emacsen. | ||
| 328 | ;;;###autoload(autoload 'tramp-archive-file-name-handler "tramp-archine") | ||
| 329 | ;;;###tramp-autoload | ||
| 326 | (defun tramp-archive-file-name-handler (operation &rest args) | 330 | (defun tramp-archive-file-name-handler (operation &rest args) |
| 327 | "Invoke the file archive related OPERATION. | 331 | "Invoke the file archive related OPERATION. |
| 328 | First arg specifies the OPERATION, second arg ARGS is a list of | 332 | First arg specifies the OPERATION, second arg ARGS is a list of |
| @@ -645,6 +649,10 @@ offered." | |||
| 645 | "Like `file-executable-p' for file archives." | 649 | "Like `file-executable-p' for file archives." |
| 646 | (file-executable-p (tramp-archive-gvfs-file-name filename))) | 650 | (file-executable-p (tramp-archive-gvfs-file-name filename))) |
| 647 | 651 | ||
| 652 | (defun tramp-archive-handle-file-exists-p (filename) | ||
| 653 | "Like `file-exists-p' for file archives." | ||
| 654 | (file-exists-p (tramp-archive-gvfs-file-name filename))) | ||
| 655 | |||
| 648 | (defun tramp-archive-handle-file-local-copy (filename) | 656 | (defun tramp-archive-handle-file-local-copy (filename) |
| 649 | "Like `file-local-copy' for file archives." | 657 | "Like `file-local-copy' for file archives." |
| 650 | (file-local-copy (tramp-archive-gvfs-file-name filename))) | 658 | (file-local-copy (tramp-archive-gvfs-file-name filename))) |
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 68f4fda4756..289df2f9aad 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | ;; - The key is a process. These are temporary properties related to | 48 | ;; - The key is a process. These are temporary properties related to |
| 49 | ;; an open connection. Examples: "scripts" keeps shell script | 49 | ;; an open connection. Examples: "scripts" keeps shell script |
| 50 | ;; definitions already sent to the remote shell, "last-cmd-time" is | 50 | ;; definitions already sent to the remote shell, "last-cmd-time" is |
| 51 | ;; the time stamp a command has been sent to the remote process. | 51 | ;; the timestamp a command has been sent to the remote process. |
| 52 | ;; | 52 | ;; |
| 53 | ;; - The key is nil. These are temporary properties related to the | 53 | ;; - The key is nil. These are temporary properties related to the |
| 54 | ;; local machine. Examples: "parse-passwd" and "parse-group" keep | 54 | ;; local machine. Examples: "parse-passwd" and "parse-group" keep |
| @@ -75,8 +75,9 @@ | |||
| 75 | 75 | ||
| 76 | ;;; Code: | 76 | ;;; Code: |
| 77 | 77 | ||
| 78 | (require 'tramp) | 78 | (require 'tramp-compat) |
| 79 | (autoload 'time-stamp-string "time-stamp") | 79 | (require 'tramp-loaddefs) |
| 80 | (require 'time-stamp) | ||
| 80 | 81 | ||
| 81 | ;;; -- Cache -- | 82 | ;;; -- Cache -- |
| 82 | 83 | ||
| @@ -133,11 +134,7 @@ If KEY is `tramp-cache-undefined', don't create anything, and return nil." | |||
| 133 | "Get the PROPERTY of FILE from the cache context of KEY. | 134 | "Get the PROPERTY of FILE from the cache context of KEY. |
| 134 | Return DEFAULT if not set." | 135 | Return DEFAULT if not set." |
| 135 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | 136 | ;; Unify localname. Remove hop from `tramp-file-name' structure. |
| 136 | (setq file (tramp-compat-file-name-unquote file) | 137 | (setq key (tramp-file-name-unify key file)) |
| 137 | key (copy-tramp-file-name key)) | ||
| 138 | (setf (tramp-file-name-localname key) | ||
| 139 | (tramp-run-real-handler #'directory-file-name (list file)) | ||
| 140 | (tramp-file-name-hop key) nil) | ||
| 141 | (let* ((hash (tramp-get-hash-table key)) | 138 | (let* ((hash (tramp-get-hash-table key)) |
| 142 | (cached (and (hash-table-p hash) (gethash property hash))) | 139 | (cached (and (hash-table-p hash) (gethash property hash))) |
| 143 | (cached-at (and (consp cached) (format-time-string "%T" (car cached)))) | 140 | (cached-at (and (consp cached) (format-time-string "%T" (car cached)))) |
| @@ -161,7 +158,8 @@ Return DEFAULT if not set." | |||
| 161 | 158 | ||
| 162 | (tramp-message | 159 | (tramp-message |
| 163 | key 8 "%s %s %s; inhibit: %s; cache used: %s; cached at: %s" | 160 | key 8 "%s %s %s; inhibit: %s; cache used: %s; cached at: %s" |
| 164 | file property value remote-file-name-inhibit-cache cache-used cached-at) | 161 | (tramp-file-name-localname key) |
| 162 | property value remote-file-name-inhibit-cache cache-used cached-at) | ||
| 165 | ;; For analysis purposes, count the number of getting this file attribute. | 163 | ;; For analysis purposes, count the number of getting this file attribute. |
| 166 | (when (>= tramp-verbose 10) | 164 | (when (>= tramp-verbose 10) |
| 167 | (let* ((var (intern (concat "tramp-cache-get-count-" property))) | 165 | (let* ((var (intern (concat "tramp-cache-get-count-" property))) |
| @@ -181,15 +179,12 @@ Return DEFAULT if not set." | |||
| 181 | "Set the PROPERTY of FILE to VALUE, in the cache context of KEY. | 179 | "Set the PROPERTY of FILE to VALUE, in the cache context of KEY. |
| 182 | Return VALUE." | 180 | Return VALUE." |
| 183 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | 181 | ;; Unify localname. Remove hop from `tramp-file-name' structure. |
| 184 | (setq file (tramp-compat-file-name-unquote file) | 182 | (setq key (tramp-file-name-unify key file)) |
| 185 | key (copy-tramp-file-name key)) | ||
| 186 | (setf (tramp-file-name-localname key) | ||
| 187 | (tramp-run-real-handler #'directory-file-name (list file)) | ||
| 188 | (tramp-file-name-hop key) nil) | ||
| 189 | (let ((hash (tramp-get-hash-table key))) | 183 | (let ((hash (tramp-get-hash-table key))) |
| 190 | ;; We put the timestamp there. | 184 | ;; We put the timestamp there. |
| 191 | (puthash property (cons (current-time) value) hash) | 185 | (puthash property (cons (current-time) value) hash) |
| 192 | (tramp-message key 8 "%s %s %s" file property value) | 186 | (tramp-message |
| 187 | key 8 "%s %s %s" (tramp-file-name-localname key) property value) | ||
| 193 | ;; For analysis purposes, count the number of setting this file attribute. | 188 | ;; For analysis purposes, count the number of setting this file attribute. |
| 194 | (when (>= tramp-verbose 10) | 189 | (when (>= tramp-verbose 10) |
| 195 | (let* ((var (intern (concat "tramp-cache-set-count-" property))) | 190 | (let* ((var (intern (concat "tramp-cache-set-count-" property))) |
| @@ -214,13 +209,9 @@ Return VALUE." | |||
| 214 | (defun tramp-flush-file-property (key file property) | 209 | (defun tramp-flush-file-property (key file property) |
| 215 | "Remove PROPERTY of FILE in the cache context of KEY." | 210 | "Remove PROPERTY of FILE in the cache context of KEY." |
| 216 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | 211 | ;; Unify localname. Remove hop from `tramp-file-name' structure. |
| 217 | (setq file (tramp-compat-file-name-unquote file) | 212 | (setq key (tramp-file-name-unify key file)) |
| 218 | key (copy-tramp-file-name key)) | ||
| 219 | (setf (tramp-file-name-localname key) | ||
| 220 | (tramp-run-real-handler #'directory-file-name (list file)) | ||
| 221 | (tramp-file-name-hop key) nil) | ||
| 222 | (remhash property (tramp-get-hash-table key)) | 213 | (remhash property (tramp-get-hash-table key)) |
| 223 | (tramp-message key 8 "%s %s" file property) | 214 | (tramp-message key 8 "%s %s" (tramp-file-name-localname key) property) |
| 224 | (when (>= tramp-verbose 10) | 215 | (when (>= tramp-verbose 10) |
| 225 | (let ((var (intern (concat "tramp-cache-set-count-" property)))) | 216 | (let ((var (intern (concat "tramp-cache-set-count-" property)))) |
| 226 | (makunbound var)))) | 217 | (makunbound var)))) |
| @@ -232,10 +223,7 @@ Return VALUE." | |||
| 232 | (when-let ((file (file-name-directory file)) | 223 | (when-let ((file (file-name-directory file)) |
| 233 | (file (directory-file-name file))) | 224 | (file (directory-file-name file))) |
| 234 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | 225 | ;; Unify localname. Remove hop from `tramp-file-name' structure. |
| 235 | (setq file (tramp-compat-file-name-unquote file) | 226 | (setq key (tramp-file-name-unify key file)) |
| 236 | key (copy-tramp-file-name key)) | ||
| 237 | (setf (tramp-file-name-localname key) file | ||
| 238 | (tramp-file-name-hop key) nil) | ||
| 239 | (dolist (property (hash-table-keys (tramp-get-hash-table key))) | 227 | (dolist (property (hash-table-keys (tramp-get-hash-table key))) |
| 240 | (when (string-match-p | 228 | (when (string-match-p |
| 241 | "^\\(directory-\\|file-name-all-completions\\|file-entries\\)" | 229 | "^\\(directory-\\|file-name-all-completions\\|file-entries\\)" |
| @@ -245,14 +233,10 @@ Return VALUE." | |||
| 245 | ;;;###tramp-autoload | 233 | ;;;###tramp-autoload |
| 246 | (defun tramp-flush-file-properties (key file) | 234 | (defun tramp-flush-file-properties (key file) |
| 247 | "Remove all properties of FILE in the cache context of KEY." | 235 | "Remove all properties of FILE in the cache context of KEY." |
| 248 | (let* ((file (tramp-run-real-handler #'directory-file-name (list file))) | 236 | (let ((truename (tramp-get-file-property key file "file-truename"))) |
| 249 | (truename (tramp-get-file-property key file "file-truename"))) | ||
| 250 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | 237 | ;; Unify localname. Remove hop from `tramp-file-name' structure. |
| 251 | (setq file (tramp-compat-file-name-unquote file) | 238 | (setq key (tramp-file-name-unify key file)) |
| 252 | key (copy-tramp-file-name key)) | 239 | (tramp-message key 8 "%s" (tramp-file-name-localname key)) |
| 253 | (setf (tramp-file-name-localname key) file | ||
| 254 | (tramp-file-name-hop key) nil) | ||
| 255 | (tramp-message key 8 "%s" file) | ||
| 256 | (remhash key tramp-cache-data) | 240 | (remhash key tramp-cache-data) |
| 257 | ;; Remove file properties of symlinks. | 241 | ;; Remove file properties of symlinks. |
| 258 | (when (and (stringp truename) | 242 | (when (and (stringp truename) |
| @@ -265,9 +249,8 @@ Return VALUE." | |||
| 265 | (defun tramp-flush-directory-properties (key directory) | 249 | (defun tramp-flush-directory-properties (key directory) |
| 266 | "Remove all properties of DIRECTORY in the cache context of KEY. | 250 | "Remove all properties of DIRECTORY in the cache context of KEY. |
| 267 | Remove also properties of all files in subdirectories." | 251 | Remove also properties of all files in subdirectories." |
| 268 | (setq directory (tramp-compat-file-name-unquote directory)) | 252 | (let* ((directory |
| 269 | (let* ((directory (tramp-run-real-handler | 253 | (directory-file-name (tramp-compat-file-name-unquote directory))) |
| 270 | #'directory-file-name (list directory))) | ||
| 271 | (truename (tramp-get-file-property key directory "file-truename"))) | 254 | (truename (tramp-get-file-property key directory "file-truename"))) |
| 272 | (tramp-message key 8 "%s" directory) | 255 | (tramp-message key 8 "%s" directory) |
| 273 | (dolist (key (hash-table-keys tramp-cache-data)) | 256 | (dolist (key (hash-table-keys tramp-cache-data)) |
| @@ -288,6 +271,7 @@ Remove also properties of all files in subdirectories." | |||
| 288 | ;; not show proper directory contents when a file has been copied or | 271 | ;; not show proper directory contents when a file has been copied or |
| 289 | ;; deleted before. We must apply `save-match-data', because it would | 272 | ;; deleted before. We must apply `save-match-data', because it would |
| 290 | ;; corrupt other packages otherwise (reported from org). | 273 | ;; corrupt other packages otherwise (reported from org). |
| 274 | ;;;###tramp-autoload | ||
| 291 | (defun tramp-flush-file-function () | 275 | (defun tramp-flush-file-function () |
| 292 | "Flush all Tramp cache properties from `buffer-file-name'. | 276 | "Flush all Tramp cache properties from `buffer-file-name'. |
| 293 | This is suppressed for temporary buffers." | 277 | This is suppressed for temporary buffers." |
| @@ -299,8 +283,8 @@ This is suppressed for temporary buffers." | |||
| 299 | default-directory)) | 283 | default-directory)) |
| 300 | (tramp-verbose 0)) | 284 | (tramp-verbose 0)) |
| 301 | (when (tramp-tramp-file-p bfn) | 285 | (when (tramp-tramp-file-p bfn) |
| 302 | (with-parsed-tramp-file-name bfn nil | 286 | (tramp-flush-file-properties |
| 303 | (tramp-flush-file-properties v localname))))))) | 287 | (tramp-dissect-file-name bfn) (tramp-file-local-name bfn))))))) |
| 304 | 288 | ||
| 305 | (add-hook 'before-revert-hook #'tramp-flush-file-function) | 289 | (add-hook 'before-revert-hook #'tramp-flush-file-function) |
| 306 | (add-hook 'eshell-pre-command-hook #'tramp-flush-file-function) | 290 | (add-hook 'eshell-pre-command-hook #'tramp-flush-file-function) |
| @@ -314,6 +298,61 @@ This is suppressed for temporary buffers." | |||
| 314 | (remove-hook 'kill-buffer-hook | 298 | (remove-hook 'kill-buffer-hook |
| 315 | #'tramp-flush-file-function))) | 299 | #'tramp-flush-file-function))) |
| 316 | 300 | ||
| 301 | ;;;###tramp-autoload | ||
| 302 | (defmacro with-tramp-file-property (key file property &rest body) | ||
| 303 | "Check in Tramp cache for PROPERTY, otherwise execute BODY and set cache. | ||
| 304 | FILE must be a local file name on a connection identified via KEY." | ||
| 305 | (declare (indent 3) (debug t)) | ||
| 306 | `(let ((value (tramp-get-file-property | ||
| 307 | ,key ,file ,property tramp-cache-undefined))) | ||
| 308 | (when (eq value tramp-cache-undefined) | ||
| 309 | ;; We cannot pass @body as parameter to | ||
| 310 | ;; `tramp-set-file-property' because it mangles our debug | ||
| 311 | ;; messages. | ||
| 312 | (setq value (progn ,@body)) | ||
| 313 | (tramp-set-file-property ,key ,file ,property value)) | ||
| 314 | value)) | ||
| 315 | |||
| 316 | ;;;###tramp-autoload | ||
| 317 | (defmacro with-tramp-saved-file-property (key file property &rest body) | ||
| 318 | "Save PROPERTY, run BODY, reset PROPERTY. | ||
| 319 | Preserve timestamps." | ||
| 320 | (declare (indent 3) (debug t)) | ||
| 321 | `(progn | ||
| 322 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | ||
| 323 | (setq ,key (tramp-file-name-unify ,key ,file)) | ||
| 324 | (let* ((hash (tramp-get-hash-table ,key)) | ||
| 325 | (cached (and (hash-table-p hash) (gethash ,property hash)))) | ||
| 326 | (unwind-protect (progn ,@body) | ||
| 327 | ;; Reset PROPERTY. Recompute hash, it could have been flushed. | ||
| 328 | (setq hash (tramp-get-hash-table ,key)) | ||
| 329 | (if (consp cached) | ||
| 330 | (puthash ,property cached hash) | ||
| 331 | (remhash ,property hash)))))) | ||
| 332 | |||
| 333 | ;;;###tramp-autoload | ||
| 334 | (defmacro with-tramp-saved-file-properties (key file properties &rest body) | ||
| 335 | "Save PROPERTIES, run BODY, reset PROPERTIES. | ||
| 336 | PROPERTIES is a list of file properties (strings). | ||
| 337 | Preserve timestamps." | ||
| 338 | (declare (indent 3) (debug t)) | ||
| 339 | `(progn | ||
| 340 | ;; Unify localname. Remove hop from `tramp-file-name' structure. | ||
| 341 | (setq ,key (tramp-file-name-unify ,key ,file)) | ||
| 342 | (let* ((hash (tramp-get-hash-table ,key)) | ||
| 343 | (values | ||
| 344 | (and (hash-table-p hash) | ||
| 345 | (mapcar | ||
| 346 | (lambda (property) (cons property (gethash property hash))) | ||
| 347 | ,properties)))) | ||
| 348 | (unwind-protect (progn ,@body) | ||
| 349 | ;; Reset PROPERTIES. Recompute hash, it could have been flushed. | ||
| 350 | (setq hash (tramp-get-hash-table ,key)) | ||
| 351 | (dolist (value values) | ||
| 352 | (if (consp (cdr value)) | ||
| 353 | (puthash (car value) (cdr value) hash) | ||
| 354 | (remhash (car value) hash))))))) | ||
| 355 | |||
| 317 | ;;; -- Properties -- | 356 | ;;; -- Properties -- |
| 318 | 357 | ||
| 319 | ;;;###tramp-autoload | 358 | ;;;###tramp-autoload |
| @@ -397,6 +436,57 @@ used to cache connection properties of the local machine." | |||
| 397 | (remhash key tramp-cache-data)) | 436 | (remhash key tramp-cache-data)) |
| 398 | 437 | ||
| 399 | ;;;###tramp-autoload | 438 | ;;;###tramp-autoload |
| 439 | (defmacro with-tramp-connection-property (key property &rest body) | ||
| 440 | "Check in Tramp for property PROPERTY, otherwise execute BODY and set." | ||
| 441 | (declare (indent 2) (debug t)) | ||
| 442 | `(let ((value (tramp-get-connection-property | ||
| 443 | ,key ,property tramp-cache-undefined))) | ||
| 444 | (when (eq value tramp-cache-undefined) | ||
| 445 | ;; We cannot pass ,@body as parameter to | ||
| 446 | ;; `tramp-set-connection-property' because it mangles our debug | ||
| 447 | ;; messages. | ||
| 448 | (setq value (progn ,@body)) | ||
| 449 | (tramp-set-connection-property ,key ,property value)) | ||
| 450 | value)) | ||
| 451 | |||
| 452 | ;;;###tramp-autoload | ||
| 453 | (defmacro with-tramp-saved-connection-property (key property &rest body) | ||
| 454 | "Save PROPERTY, run BODY, reset PROPERTY." | ||
| 455 | (declare (indent 2) (debug t)) | ||
| 456 | `(progn | ||
| 457 | (setq ,key (tramp-file-name-unify ,key)) | ||
| 458 | (let* ((hash (tramp-get-hash-table ,key)) | ||
| 459 | (cached (and (hash-table-p hash) | ||
| 460 | (gethash ,property hash tramp-cache-undefined)))) | ||
| 461 | (unwind-protect (progn ,@body) | ||
| 462 | ;; Reset PROPERTY. Recompute hash, it could have been flushed. | ||
| 463 | (setq hash (tramp-get-hash-table ,key)) | ||
| 464 | (if (not (eq cached tramp-cache-undefined)) | ||
| 465 | (puthash ,property cached hash) | ||
| 466 | (remhash ,property hash)))))) | ||
| 467 | |||
| 468 | ;;;###tramp-autoload | ||
| 469 | (defmacro with-tramp-saved-connection-properties (key properties &rest body) | ||
| 470 | "Save PROPERTIES, run BODY, reset PROPERTIES. | ||
| 471 | PROPERTIES is a list of file properties (strings)." | ||
| 472 | (declare (indent 2) (debug t)) | ||
| 473 | `(progn | ||
| 474 | (setq ,key (tramp-file-name-unify ,key)) | ||
| 475 | (let* ((hash (tramp-get-hash-table ,key)) | ||
| 476 | (values | ||
| 477 | (mapcar | ||
| 478 | (lambda (property) | ||
| 479 | (cons property (gethash property hash tramp-cache-undefined))) | ||
| 480 | ,properties))) | ||
| 481 | (unwind-protect (progn ,@body) | ||
| 482 | ;; Reset PROPERTIES. Recompute hash, it could have been flushed. | ||
| 483 | (setq hash (tramp-get-hash-table ,key)) | ||
| 484 | (dolist (value values) | ||
| 485 | (if (not (eq (cdr value) tramp-cache-undefined)) | ||
| 486 | (puthash (car value) (cdr value) hash) | ||
| 487 | (remhash (car value) hash))))))) | ||
| 488 | |||
| 489 | ;;;###tramp-autoload | ||
| 400 | (defun tramp-cache-print (table) | 490 | (defun tramp-cache-print (table) |
| 401 | "Print hash table TABLE." | 491 | "Print hash table TABLE." |
| 402 | (when (hash-table-p table) | 492 | (when (hash-table-p table) |
diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 5c8012e553b..f7704864ec6 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el | |||
| @@ -139,7 +139,7 @@ When called interactively, a Tramp connection has to be selected." | |||
| 139 | (when (bufferp buf) (kill-buffer buf))) | 139 | (when (bufferp buf) (kill-buffer buf))) |
| 140 | 140 | ||
| 141 | ;; Flush file cache. | 141 | ;; Flush file cache. |
| 142 | (tramp-flush-directory-properties vec "") | 142 | (tramp-flush-directory-properties vec "/") |
| 143 | 143 | ||
| 144 | ;; Flush connection cache. | 144 | ;; Flush connection cache. |
| 145 | (tramp-flush-connection-properties vec) | 145 | (tramp-flush-connection-properties vec) |
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index 4fcd132ab0a..7f385292626 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el | |||
| @@ -824,24 +824,21 @@ WILDCARD is not supported." | |||
| 824 | 824 | ||
| 825 | (defun tramp-crypt-handle-set-file-modes (filename mode &optional flag) | 825 | (defun tramp-crypt-handle-set-file-modes (filename mode &optional flag) |
| 826 | "Like `set-file-modes' for Tramp files." | 826 | "Like `set-file-modes' for Tramp files." |
| 827 | (with-parsed-tramp-file-name filename nil | 827 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 828 | (tramp-flush-file-properties v localname) | ||
| 829 | (let (tramp-crypt-enabled) | 828 | (let (tramp-crypt-enabled) |
| 830 | (tramp-compat-set-file-modes | 829 | (tramp-compat-set-file-modes |
| 831 | (tramp-crypt-encrypt-file-name filename) mode flag)))) | 830 | (tramp-crypt-encrypt-file-name filename) mode flag)))) |
| 832 | 831 | ||
| 833 | (defun tramp-crypt-handle-set-file-times (filename &optional time flag) | 832 | (defun tramp-crypt-handle-set-file-times (filename &optional time flag) |
| 834 | "Like `set-file-times' for Tramp files." | 833 | "Like `set-file-times' for Tramp files." |
| 835 | (with-parsed-tramp-file-name filename nil | 834 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 836 | (tramp-flush-file-properties v localname) | ||
| 837 | (let (tramp-crypt-enabled) | 835 | (let (tramp-crypt-enabled) |
| 838 | (tramp-compat-set-file-times | 836 | (tramp-compat-set-file-times |
| 839 | (tramp-crypt-encrypt-file-name filename) time flag)))) | 837 | (tramp-crypt-encrypt-file-name filename) time flag)))) |
| 840 | 838 | ||
| 841 | (defun tramp-crypt-handle-set-file-uid-gid (filename &optional uid gid) | 839 | (defun tramp-crypt-handle-set-file-uid-gid (filename &optional uid gid) |
| 842 | "Like `tramp-set-file-uid-gid' for Tramp files." | 840 | "Like `tramp-set-file-uid-gid' for Tramp files." |
| 843 | (with-parsed-tramp-file-name filename nil | 841 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 844 | (tramp-flush-file-properties v localname) | ||
| 845 | (let (tramp-crypt-enabled) | 842 | (let (tramp-crypt-enabled) |
| 846 | (tramp-set-file-uid-gid | 843 | (tramp-set-file-uid-gid |
| 847 | (tramp-crypt-encrypt-file-name filename) uid gid)))) | 844 | (tramp-crypt-encrypt-file-name filename) uid gid)))) |
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index d4bbb944793..dd7e0f9f342 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | (require 'tramp) | 31 | (require 'tramp) |
| 32 | 32 | ||
| 33 | ;; Pacify byte-compiler. | 33 | ;; Pacify byte-compiler. |
| 34 | (declare-function tramp-archive-file-name-handler "tramp-archive") | ||
| 35 | (defvar ange-ftp-ftp-name-arg) | 34 | (defvar ange-ftp-ftp-name-arg) |
| 36 | (defvar ange-ftp-ftp-name-res) | 35 | (defvar ange-ftp-ftp-name-res) |
| 37 | (defvar ange-ftp-name-format) | 36 | (defvar ange-ftp-name-format) |
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 2f97b2cb916..0b40ff867f2 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el | |||
| @@ -960,6 +960,15 @@ The global value will always be nil; it is bound where needed.") | |||
| 960 | 960 | ||
| 961 | ;; File name primitives. | 961 | ;; File name primitives. |
| 962 | 962 | ||
| 963 | (defun tramp-gvfs-info (filename &optional arg) | ||
| 964 | "Check FILENAME via `gvfs-info'. | ||
| 965 | Set file property \"file-exists-p\" with the result." | ||
| 966 | (with-parsed-tramp-file-name filename nil | ||
| 967 | (tramp-set-file-property | ||
| 968 | v localname "file-exists-p" | ||
| 969 | (tramp-gvfs-send-command | ||
| 970 | v "gvfs-info" arg (tramp-gvfs-url-file-name filename))))) | ||
| 971 | |||
| 963 | (defun tramp-gvfs-do-copy-or-rename-file | 972 | (defun tramp-gvfs-do-copy-or-rename-file |
| 964 | (op filename newname &optional ok-if-already-exists keep-date | 973 | (op filename newname &optional ok-if-already-exists keep-date |
| 965 | preserve-uid-gid preserve-extended-attributes) | 974 | preserve-uid-gid preserve-extended-attributes) |
| @@ -1046,12 +1055,9 @@ file names." | |||
| 1046 | ;; code in case of direct copy/move. Apply | 1055 | ;; code in case of direct copy/move. Apply |
| 1047 | ;; sanity checks. | 1056 | ;; sanity checks. |
| 1048 | (or (not equal-remote) | 1057 | (or (not equal-remote) |
| 1049 | (tramp-gvfs-send-command | 1058 | (tramp-gvfs-info newname) |
| 1050 | v "gvfs-info" (tramp-gvfs-url-file-name newname)) | ||
| 1051 | (eq op 'copy) | 1059 | (eq op 'copy) |
| 1052 | (not (tramp-gvfs-send-command | 1060 | (not (tramp-gvfs-info filename)))) |
| 1053 | v "gvfs-info" | ||
| 1054 | (tramp-gvfs-url-file-name filename))))) | ||
| 1055 | 1061 | ||
| 1056 | (if (or (not equal-remote) | 1062 | (if (or (not equal-remote) |
| 1057 | (and equal-remote | 1063 | (and equal-remote |
| @@ -1111,8 +1117,9 @@ file names." | |||
| 1111 | (tramp-error | 1117 | (tramp-error |
| 1112 | v 'file-error "Couldn't delete non-empty %s" directory))) | 1118 | v 'file-error "Couldn't delete non-empty %s" directory))) |
| 1113 | 1119 | ||
| 1114 | (unless (tramp-gvfs-send-command | 1120 | (unless (and (tramp-gvfs-send-command |
| 1115 | v "gvfs-rm" (tramp-gvfs-url-file-name directory)) | 1121 | v "gvfs-rm" (tramp-gvfs-url-file-name directory)) |
| 1122 | (not (tramp-gvfs-info directory))) | ||
| 1116 | ;; Propagate the error. | 1123 | ;; Propagate the error. |
| 1117 | (with-current-buffer (tramp-get-connection-buffer v) | 1124 | (with-current-buffer (tramp-get-connection-buffer v) |
| 1118 | (goto-char (point-min)) | 1125 | (goto-char (point-min)) |
| @@ -1125,8 +1132,9 @@ file names." | |||
| 1125 | (tramp-flush-file-properties v localname) | 1132 | (tramp-flush-file-properties v localname) |
| 1126 | (if (and delete-by-moving-to-trash trash) | 1133 | (if (and delete-by-moving-to-trash trash) |
| 1127 | (move-file-to-trash filename) | 1134 | (move-file-to-trash filename) |
| 1128 | (unless (tramp-gvfs-send-command | 1135 | (unless (and (tramp-gvfs-send-command |
| 1129 | v "gvfs-rm" (tramp-gvfs-url-file-name filename)) | 1136 | v "gvfs-rm" (tramp-gvfs-url-file-name filename)) |
| 1137 | (not (tramp-gvfs-info filename))) | ||
| 1130 | ;; Propagate the error. | 1138 | ;; Propagate the error. |
| 1131 | (with-current-buffer (tramp-get-connection-buffer v) | 1139 | (with-current-buffer (tramp-get-connection-buffer v) |
| 1132 | (goto-char (point-min)) | 1140 | (goto-char (point-min)) |
| @@ -1239,10 +1247,8 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1239 | (if file-system " system" "") localname) | 1247 | (if file-system " system" "") localname) |
| 1240 | ;; Send command. | 1248 | ;; Send command. |
| 1241 | (if file-system | 1249 | (if file-system |
| 1242 | (tramp-gvfs-send-command | 1250 | (tramp-gvfs-info filename "--filesystem") |
| 1243 | v "gvfs-info" "--filesystem" (tramp-gvfs-url-file-name filename)) | 1251 | (tramp-gvfs-info filename)) |
| 1244 | (tramp-gvfs-send-command | ||
| 1245 | v "gvfs-info" (tramp-gvfs-url-file-name filename))) | ||
| 1246 | ;; Parse output. | 1252 | ;; Parse output. |
| 1247 | (with-current-buffer (tramp-get-connection-buffer v) | 1253 | (with-current-buffer (tramp-get-connection-buffer v) |
| 1248 | (goto-char (point-min)) | 1254 | (goto-char (point-min)) |
| @@ -1547,8 +1553,10 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1547 | (make-directory ldir parents)) | 1553 | (make-directory ldir parents)) |
| 1548 | ;; Just do it. | 1554 | ;; Just do it. |
| 1549 | (or (when-let ((mkdir-succeeded | 1555 | (or (when-let ((mkdir-succeeded |
| 1550 | (tramp-gvfs-send-command | 1556 | (and |
| 1551 | v "gvfs-mkdir" (tramp-gvfs-url-file-name dir)))) | 1557 | (tramp-gvfs-send-command |
| 1558 | v "gvfs-mkdir" (tramp-gvfs-url-file-name dir)) | ||
| 1559 | (tramp-gvfs-info dir)))) | ||
| 1552 | (set-file-modes dir (default-file-modes)) | 1560 | (set-file-modes dir (default-file-modes)) |
| 1553 | mkdir-succeeded) | 1561 | mkdir-succeeded) |
| 1554 | (and parents (file-directory-p dir)) | 1562 | (and parents (file-directory-p dir)) |
| @@ -1582,16 +1590,14 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1582 | 1590 | ||
| 1583 | (defun tramp-gvfs-handle-set-file-modes (filename mode &optional flag) | 1591 | (defun tramp-gvfs-handle-set-file-modes (filename mode &optional flag) |
| 1584 | "Like `set-file-modes' for Tramp files." | 1592 | "Like `set-file-modes' for Tramp files." |
| 1585 | (with-parsed-tramp-file-name filename nil | 1593 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1586 | (tramp-flush-file-properties v localname) | ||
| 1587 | (tramp-gvfs-set-attribute | 1594 | (tramp-gvfs-set-attribute |
| 1588 | v (if (eq flag 'nofollow) "-nt" "-t") "uint32" | 1595 | v (if (eq flag 'nofollow) "-nt" "-t") "uint32" |
| 1589 | (tramp-gvfs-url-file-name filename) "unix::mode" (number-to-string mode)))) | 1596 | (tramp-gvfs-url-file-name filename) "unix::mode" (number-to-string mode)))) |
| 1590 | 1597 | ||
| 1591 | (defun tramp-gvfs-handle-set-file-times (filename &optional time flag) | 1598 | (defun tramp-gvfs-handle-set-file-times (filename &optional time flag) |
| 1592 | "Like `set-file-times' for Tramp files." | 1599 | "Like `set-file-times' for Tramp files." |
| 1593 | (with-parsed-tramp-file-name filename nil | 1600 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1594 | (tramp-flush-file-properties v localname) | ||
| 1595 | (tramp-gvfs-set-attribute | 1601 | (tramp-gvfs-set-attribute |
| 1596 | v (if (eq flag 'nofollow) "-nt" "-t") "uint64" | 1602 | v (if (eq flag 'nofollow) "-nt" "-t") "uint64" |
| 1597 | (tramp-gvfs-url-file-name filename) "time::modified" | 1603 | (tramp-gvfs-url-file-name filename) "time::modified" |
| @@ -1644,8 +1650,7 @@ ID-FORMAT valid values are `string' and `integer'." | |||
| 1644 | 1650 | ||
| 1645 | (defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid) | 1651 | (defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid) |
| 1646 | "Like `tramp-set-file-uid-gid' for Tramp files." | 1652 | "Like `tramp-set-file-uid-gid' for Tramp files." |
| 1647 | (with-parsed-tramp-file-name filename nil | 1653 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1648 | (tramp-flush-file-properties v localname) | ||
| 1649 | (when (natnump uid) | 1654 | (when (natnump uid) |
| 1650 | (tramp-gvfs-set-attribute | 1655 | (tramp-gvfs-set-attribute |
| 1651 | v "-t" "uint32" | 1656 | v "-t" "uint32" |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 172933859c1..d88e388cd56 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1113,7 +1113,8 @@ component is used as the target of the symlink." | |||
| 1113 | (tramp-file-name-equal-p v (tramp-dissect-file-name target))) | 1113 | (tramp-file-name-equal-p v (tramp-dissect-file-name target))) |
| 1114 | (setq target (tramp-file-local-name (expand-file-name target)))) | 1114 | (setq target (tramp-file-local-name (expand-file-name target)))) |
| 1115 | ;; There could be a cyclic link. | 1115 | ;; There could be a cyclic link. |
| 1116 | (tramp-flush-file-properties v target)) | 1116 | (tramp-flush-file-properties |
| 1117 | v (expand-file-name target (tramp-file-local-name default-directory)))) | ||
| 1117 | 1118 | ||
| 1118 | ;; If TARGET is still remote, quote it. | 1119 | ;; If TARGET is still remote, quote it. |
| 1119 | (if (tramp-tramp-file-p target) | 1120 | (if (tramp-tramp-file-p target) |
| @@ -1465,12 +1466,11 @@ of." | |||
| 1465 | 1466 | ||
| 1466 | (defun tramp-sh-handle-set-file-modes (filename mode &optional flag) | 1467 | (defun tramp-sh-handle-set-file-modes (filename mode &optional flag) |
| 1467 | "Like `set-file-modes' for Tramp files." | 1468 | "Like `set-file-modes' for Tramp files." |
| 1468 | (with-parsed-tramp-file-name filename nil | 1469 | ;; We need "chmod -h" when the flag is set. |
| 1469 | ;; We need "chmod -h" when the flag is set. | 1470 | (when (or (not (eq flag 'nofollow)) |
| 1470 | (when (or (not (eq flag 'nofollow)) | 1471 | (not (file-symlink-p filename)) |
| 1471 | (not (file-symlink-p filename)) | 1472 | (tramp-get-remote-chmod-h (tramp-dissect-file-name filename))) |
| 1472 | (tramp-get-remote-chmod-h v)) | 1473 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1473 | (tramp-flush-file-properties v localname) | ||
| 1474 | ;; FIXME: extract the proper text from chmod's stderr. | 1474 | ;; FIXME: extract the proper text from chmod's stderr. |
| 1475 | (tramp-barf-unless-okay | 1475 | (tramp-barf-unless-okay |
| 1476 | v | 1476 | v |
| @@ -1482,9 +1482,8 @@ of." | |||
| 1482 | 1482 | ||
| 1483 | (defun tramp-sh-handle-set-file-times (filename &optional time flag) | 1483 | (defun tramp-sh-handle-set-file-times (filename &optional time flag) |
| 1484 | "Like `set-file-times' for Tramp files." | 1484 | "Like `set-file-times' for Tramp files." |
| 1485 | (with-parsed-tramp-file-name filename nil | 1485 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1486 | (when (tramp-get-remote-touch v) | 1486 | (when (tramp-get-remote-touch v) |
| 1487 | (tramp-flush-file-properties v localname) | ||
| 1488 | (let ((time | 1487 | (let ((time |
| 1489 | (if (or (null time) | 1488 | (if (or (null time) |
| 1490 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) | 1489 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) |
| @@ -1543,9 +1542,9 @@ ID-FORMAT valid values are `string' and `integer'." | |||
| 1543 | ;; another implementation, see `dired-do-chown'. OTOH, it is mostly | 1542 | ;; another implementation, see `dired-do-chown'. OTOH, it is mostly |
| 1544 | ;; working with su(do)? when it is needed, so it shall succeed in | 1543 | ;; working with su(do)? when it is needed, so it shall succeed in |
| 1545 | ;; the majority of cases. | 1544 | ;; the majority of cases. |
| 1546 | ;; Don't modify `last-coding-system-used' by accident. | 1545 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1547 | (let ((last-coding-system-used last-coding-system-used)) | 1546 | ;; Don't modify `last-coding-system-used' by accident. |
| 1548 | (with-parsed-tramp-file-name filename nil | 1547 | (let ((last-coding-system-used last-coding-system-used)) |
| 1549 | (if (and (zerop (user-uid)) (tramp-local-host-p v)) | 1548 | (if (and (zerop (user-uid)) (tramp-local-host-p v)) |
| 1550 | ;; If we are root on the local host, we can do it directly. | 1549 | ;; If we are root on the local host, we can do it directly. |
| 1551 | (tramp-set-file-uid-gid localname uid gid) | 1550 | (tramp-set-file-uid-gid localname uid gid) |
| @@ -1767,10 +1766,11 @@ ID-FORMAT valid values are `string' and `integer'." | |||
| 1767 | ;; files. | 1766 | ;; files. |
| 1768 | (defun tramp-sh-handle-file-name-all-completions (filename directory) | 1767 | (defun tramp-sh-handle-file-name-all-completions (filename directory) |
| 1769 | "Like `file-name-all-completions' for Tramp files." | 1768 | "Like `file-name-all-completions' for Tramp files." |
| 1770 | (unless (tramp-compat-string-search "/" filename) | 1769 | (with-parsed-tramp-file-name (expand-file-name directory) nil |
| 1771 | (all-completions | 1770 | (when (and (not (tramp-compat-string-search "/" filename)) |
| 1772 | filename | 1771 | (tramp-connectable-p v)) |
| 1773 | (with-parsed-tramp-file-name (expand-file-name directory) nil | 1772 | (all-completions |
| 1773 | filename | ||
| 1774 | (with-tramp-file-property v localname "file-name-all-completions" | 1774 | (with-tramp-file-property v localname "file-name-all-completions" |
| 1775 | (let (result) | 1775 | (let (result) |
| 1776 | ;; Get a list of directories and files, including reliably | 1776 | ;; Get a list of directories and files, including reliably |
| @@ -2197,6 +2197,8 @@ the uid and gid from FILENAME." | |||
| 2197 | (file-name-directory (concat prefix localname2))) | 2197 | (file-name-directory (concat prefix localname2))) |
| 2198 | (or (file-directory-p (concat prefix localname2)) | 2198 | (or (file-directory-p (concat prefix localname2)) |
| 2199 | (file-writable-p (concat prefix localname2)))) | 2199 | (file-writable-p (concat prefix localname2)))) |
| 2200 | (with-parsed-tramp-file-name prefix nil | ||
| 2201 | (tramp-flush-file-properties v localname2)) | ||
| 2200 | (tramp-do-copy-or-rename-file-directly | 2202 | (tramp-do-copy-or-rename-file-directly |
| 2201 | op (concat prefix localname1) (concat prefix localname2) | 2203 | op (concat prefix localname1) (concat prefix localname2) |
| 2202 | ok-if-already-exists keep-date preserve-uid-gid) | 2204 | ok-if-already-exists keep-date preserve-uid-gid) |
| @@ -2406,52 +2408,52 @@ The method used must be an out-of-band method." | |||
| 2406 | 2408 | ||
| 2407 | (with-temp-buffer | 2409 | (with-temp-buffer |
| 2408 | (unwind-protect | 2410 | (unwind-protect |
| 2409 | (with-tramp-saved-connection-property v "process-name" | 2411 | (with-tramp-saved-connection-properties |
| 2410 | (with-tramp-saved-connection-property v "process-buffer" | 2412 | v '("process-name" "process-buffer") |
| 2411 | ;; The default directory must be remote. | 2413 | ;; The default directory must be remote. |
| 2412 | (let ((default-directory | 2414 | (let ((default-directory |
| 2413 | (file-name-directory (if v1 filename newname))) | 2415 | (file-name-directory (if v1 filename newname))) |
| 2414 | (process-environment (copy-sequence process-environment))) | 2416 | (process-environment (copy-sequence process-environment))) |
| 2415 | ;; Set the transfer process properties. | 2417 | ;; Set the transfer process properties. |
| 2416 | (tramp-set-connection-property | 2418 | (tramp-set-connection-property |
| 2417 | v "process-name" (buffer-name (current-buffer))) | 2419 | v "process-name" (buffer-name (current-buffer))) |
| 2418 | (tramp-set-connection-property | 2420 | (tramp-set-connection-property |
| 2419 | v "process-buffer" (current-buffer)) | 2421 | v "process-buffer" (current-buffer)) |
| 2420 | (when copy-env | 2422 | (when copy-env |
| 2421 | (tramp-message | 2423 | (tramp-message |
| 2422 | v 6 "%s=\"%s\"" | 2424 | v 6 "%s=\"%s\"" |
| 2423 | (car copy-env) (string-join (cdr copy-env) " ")) | 2425 | (car copy-env) (string-join (cdr copy-env) " ")) |
| 2424 | (setenv (car copy-env) (string-join (cdr copy-env) " "))) | 2426 | (setenv (car copy-env) (string-join (cdr copy-env) " "))) |
| 2425 | (setq | 2427 | (setq |
| 2426 | copy-args | 2428 | copy-args |
| 2427 | (append | 2429 | (append |
| 2428 | copy-args | 2430 | copy-args |
| 2429 | (if remote-copy-program | 2431 | (if remote-copy-program |
| 2430 | (list (if v1 (concat ">" target) (concat "<" source))) | 2432 | (list (if v1 (concat ">" target) (concat "<" source))) |
| 2431 | (list source target))) | 2433 | (list source target))) |
| 2432 | ;; Use an asynchronous process. By this, password | 2434 | ;; Use an asynchronous process. By this, password |
| 2433 | ;; can be handled. We don't set a timeout, because | 2435 | ;; can be handled. We don't set a timeout, because |
| 2434 | ;; the copying of large files can last longer than | 2436 | ;; the copying of large files can last longer than 60 |
| 2435 | ;; 60 secs. | 2437 | ;; secs. |
| 2436 | p (let ((default-directory | 2438 | p (let ((default-directory |
| 2437 | tramp-compat-temporary-file-directory)) | 2439 | tramp-compat-temporary-file-directory)) |
| 2438 | (apply | 2440 | (apply |
| 2439 | #'start-process | 2441 | #'start-process |
| 2440 | (tramp-get-connection-name v) | 2442 | (tramp-get-connection-name v) |
| 2441 | (tramp-get-connection-buffer v) | 2443 | (tramp-get-connection-buffer v) |
| 2442 | copy-program copy-args))) | 2444 | copy-program copy-args))) |
| 2443 | (tramp-message v 6 "%s" (string-join (process-command p) " ")) | 2445 | (tramp-message v 6 "%s" (string-join (process-command p) " ")) |
| 2444 | (process-put p 'vector v) | 2446 | (process-put p 'vector v) |
| 2445 | (process-put p 'adjust-window-size-function #'ignore) | 2447 | (process-put p 'adjust-window-size-function #'ignore) |
| 2446 | (set-process-query-on-exit-flag p nil) | 2448 | (set-process-query-on-exit-flag p nil) |
| 2447 | 2449 | ||
| 2448 | ;; We must adapt `tramp-local-end-of-line' for sending | 2450 | ;; We must adapt `tramp-local-end-of-line' for sending |
| 2449 | ;; the password. Also, we indicate that perhaps several | 2451 | ;; the password. Also, we indicate that perhaps |
| 2450 | ;; password prompts might appear. | 2452 | ;; several password prompts might appear. |
| 2451 | (let ((tramp-local-end-of-line tramp-rsh-end-of-line) | 2453 | (let ((tramp-local-end-of-line tramp-rsh-end-of-line) |
| 2452 | (tramp-password-prompt-not-unique (and v1 v2))) | 2454 | (tramp-password-prompt-not-unique (and v1 v2))) |
| 2453 | (tramp-process-actions | 2455 | (tramp-process-actions |
| 2454 | p v nil tramp-actions-copy-out-of-band))))) | 2456 | p v nil tramp-actions-copy-out-of-band)))) |
| 2455 | 2457 | ||
| 2456 | ;; Clear the remote prompt. | 2458 | ;; Clear the remote prompt. |
| 2457 | (when (and remote-copy-program | 2459 | (when (and remote-copy-program |
| @@ -2510,12 +2512,12 @@ The method used must be an out-of-band method." | |||
| 2510 | "Like `delete-file' for Tramp files." | 2512 | "Like `delete-file' for Tramp files." |
| 2511 | (setq filename (expand-file-name filename)) | 2513 | (setq filename (expand-file-name filename)) |
| 2512 | (with-parsed-tramp-file-name filename nil | 2514 | (with-parsed-tramp-file-name filename nil |
| 2513 | (tramp-flush-file-properties v localname) | ||
| 2514 | (if (and delete-by-moving-to-trash trash) | 2515 | (if (and delete-by-moving-to-trash trash) |
| 2515 | (move-file-to-trash filename) | 2516 | (move-file-to-trash filename) |
| 2516 | (tramp-barf-unless-okay | 2517 | (tramp-barf-unless-okay |
| 2517 | v (format "rm -f %s" (tramp-shell-quote-argument localname)) | 2518 | v (format "rm -f %s" (tramp-shell-quote-argument localname)) |
| 2518 | "Couldn't delete %s" filename)))) | 2519 | "Couldn't delete %s" filename)) |
| 2520 | (tramp-flush-file-properties v localname))) | ||
| 2519 | 2521 | ||
| 2520 | ;; Dired. | 2522 | ;; Dired. |
| 2521 | 2523 | ||
| @@ -2966,102 +2968,102 @@ implementation will be used." | |||
| 2966 | name1 (format "%s<%d>" name i))) | 2968 | name1 (format "%s<%d>" name i))) |
| 2967 | (setq name name1) | 2969 | (setq name name1) |
| 2968 | 2970 | ||
| 2969 | (with-tramp-saved-connection-property v "process-name" | 2971 | (with-tramp-saved-connection-properties |
| 2970 | (with-tramp-saved-connection-property v "process-buffer" | 2972 | v '("process-name" "process-buffer") |
| 2971 | ;; Set the new process properties. | 2973 | ;; Set the new process properties. |
| 2972 | (tramp-set-connection-property v "process-name" name) | 2974 | (tramp-set-connection-property v "process-name" name) |
| 2973 | (tramp-set-connection-property v "process-buffer" buffer) | 2975 | (tramp-set-connection-property v "process-buffer" buffer) |
| 2974 | (with-current-buffer (tramp-get-connection-buffer v) | 2976 | (with-current-buffer (tramp-get-connection-buffer v) |
| 2975 | (unwind-protect | 2977 | (unwind-protect |
| 2976 | ;; We catch this event. Otherwise, | 2978 | ;; We catch this event. Otherwise, `make-process' |
| 2977 | ;; `make-process' could be called on the local | 2979 | ;; could be called on the local host. |
| 2978 | ;; host. | 2980 | (save-excursion |
| 2979 | (save-excursion | 2981 | (save-restriction |
| 2980 | (save-restriction | 2982 | ;; Activate narrowing in order to save BUFFER |
| 2981 | ;; Activate narrowing in order to save | 2983 | ;; contents. Clear also the modification |
| 2982 | ;; BUFFER contents. Clear also the | 2984 | ;; time; otherwise we might be interrupted by |
| 2983 | ;; modification time; otherwise we might be | 2985 | ;; `verify-visited-file-modtime'. |
| 2984 | ;; interrupted by `verify-visited-file-modtime'. | 2986 | (let ((buffer-undo-list t) |
| 2985 | (let ((buffer-undo-list t) | 2987 | (inhibit-read-only t) |
| 2986 | (inhibit-read-only t) | 2988 | (mark (point-max)) |
| 2987 | (mark (point-max)) | 2989 | (coding-system-for-write |
| 2988 | (coding-system-for-write | 2990 | (if (symbolp coding) coding (car coding))) |
| 2989 | (if (symbolp coding) coding (car coding))) | 2991 | (coding-system-for-read |
| 2990 | (coding-system-for-read | 2992 | (if (symbolp coding) coding (cdr coding)))) |
| 2991 | (if (symbolp coding) coding (cdr coding)))) | 2993 | (clear-visited-file-modtime) |
| 2992 | (clear-visited-file-modtime) | 2994 | (narrow-to-region (point-max) (point-max)) |
| 2995 | (catch 'suppress | ||
| 2996 | ;; Set the pid of the remote shell. This | ||
| 2997 | ;; is needed when sending signals | ||
| 2998 | ;; remotely. | ||
| 2999 | (let ((pid | ||
| 3000 | (tramp-send-command-and-read v "echo $$"))) | ||
| 3001 | (setq p (tramp-get-connection-process v)) | ||
| 3002 | (process-put p 'remote-pid pid) | ||
| 3003 | (tramp-set-connection-property | ||
| 3004 | p "remote-pid" pid)) | ||
| 3005 | ;; Disable carriage return to newline | ||
| 3006 | ;; translation. This does not work on | ||
| 3007 | ;; macOS, see Bug#50748. | ||
| 3008 | (when (and (memq connection-type '(nil pipe)) | ||
| 3009 | (not | ||
| 3010 | (tramp-check-remote-uname v "Darwin"))) | ||
| 3011 | (tramp-send-command v "stty -icrnl")) | ||
| 3012 | ;; `tramp-maybe-open-connection' and | ||
| 3013 | ;; `tramp-send-command-and-read' could | ||
| 3014 | ;; have trashed the connection buffer. | ||
| 3015 | ;; Remove this. | ||
| 3016 | (widen) | ||
| 3017 | (delete-region mark (point-max)) | ||
| 2993 | (narrow-to-region (point-max) (point-max)) | 3018 | (narrow-to-region (point-max) (point-max)) |
| 2994 | (catch 'suppress | 3019 | ;; Now do it. |
| 2995 | ;; Set the pid of the remote shell. This is | 3020 | (if command |
| 2996 | ;; needed when sending signals remotely. | 3021 | ;; Send the command. |
| 2997 | (let ((pid | 3022 | (tramp-send-command v command nil t) ; nooutput |
| 2998 | (tramp-send-command-and-read v "echo $$"))) | 3023 | ;; Check, whether a pty is associated. |
| 2999 | (setq p (tramp-get-connection-process v)) | 3024 | (unless (process-get p 'remote-tty) |
| 3000 | (process-put p 'remote-pid pid) | 3025 | (tramp-error |
| 3001 | (tramp-set-connection-property | 3026 | v 'file-error |
| 3002 | p "remote-pid" pid)) | 3027 | "pty association is not supported for `%s'" |
| 3003 | ;; Disable carriage return to newline | 3028 | name)))) |
| 3004 | ;; translation. This does not work on | 3029 | ;; Set sentinel and filter. |
| 3005 | ;; macOS, see Bug#50748. | 3030 | (when sentinel |
| 3006 | (when (and (memq connection-type '(nil pipe)) | 3031 | (set-process-sentinel p sentinel)) |
| 3007 | (not | 3032 | (when filter |
| 3008 | (tramp-check-remote-uname v "Darwin"))) | 3033 | (set-process-filter p filter)) |
| 3009 | (tramp-send-command v "stty -icrnl")) | 3034 | (process-put p 'remote-command orig-command) |
| 3010 | ;; `tramp-maybe-open-connection' and | 3035 | (tramp-set-connection-property |
| 3011 | ;; `tramp-send-command-and-read' could have | 3036 | p "remote-command" orig-command) |
| 3012 | ;; trashed the connection buffer. Remove this. | 3037 | ;; Set query flag and process marker for |
| 3013 | (widen) | 3038 | ;; this process. We ignore errors, because |
| 3014 | (delete-region mark (point-max)) | 3039 | ;; the process could have finished already. |
| 3015 | (narrow-to-region (point-max) (point-max)) | 3040 | (ignore-errors |
| 3016 | ;; Now do it. | 3041 | (set-process-query-on-exit-flag p (null noquery)) |
| 3017 | (if command | 3042 | (set-marker (process-mark p) (point))) |
| 3018 | ;; Send the command. | 3043 | ;; We must flush them here already; |
| 3019 | (tramp-send-command v command nil t) ; nooutput | 3044 | ;; otherwise `delete-file' will fail. |
| 3020 | ;; Check, whether a pty is associated. | 3045 | (tramp-flush-connection-property v "process-name") |
| 3021 | (unless (process-get p 'remote-tty) | 3046 | (tramp-flush-connection-property v "process-buffer") |
| 3022 | (tramp-error | 3047 | ;; Kill stderr process and delete named pipe. |
| 3023 | v 'file-error | 3048 | (when (bufferp stderr) |
| 3024 | "pty association is not supported for `%s'" | 3049 | (add-function |
| 3025 | name)))) | 3050 | :after (process-sentinel p) |
| 3026 | ;; Set sentinel and filter. | 3051 | (lambda (_proc _msg) |
| 3027 | (when sentinel | 3052 | (ignore-errors |
| 3028 | (set-process-sentinel p sentinel)) | 3053 | (while (accept-process-output |
| 3029 | (when filter | 3054 | (get-buffer-process stderr) 0 nil t)) |
| 3030 | (set-process-filter p filter)) | 3055 | (delete-process (get-buffer-process stderr))) |
| 3031 | (process-put p 'remote-command orig-command) | 3056 | (ignore-errors |
| 3032 | (tramp-set-connection-property | 3057 | (delete-file remote-tmpstderr))))) |
| 3033 | p "remote-command" orig-command) | 3058 | ;; Return process. |
| 3034 | ;; Set query flag and process marker for | 3059 | p))) |
| 3035 | ;; this process. We ignore errors, | 3060 | |
| 3036 | ;; because the process could have finished | 3061 | ;; Save exit. |
| 3037 | ;; already. | 3062 | (if (string-prefix-p tramp-temp-buffer-name (buffer-name)) |
| 3038 | (ignore-errors | 3063 | (ignore-errors |
| 3039 | (set-process-query-on-exit-flag p (null noquery)) | 3064 | (set-process-buffer p nil) |
| 3040 | (set-marker (process-mark p) (point))) | 3065 | (kill-buffer (current-buffer))) |
| 3041 | ;; We must flush them here already; | 3066 | (set-buffer-modified-p bmp))))))))))) |
| 3042 | ;; otherwise `delete-file' will fail. | ||
| 3043 | (tramp-flush-connection-property v "process-name") | ||
| 3044 | (tramp-flush-connection-property v "process-buffer") | ||
| 3045 | ;; Kill stderr process and delete named pipe. | ||
| 3046 | (when (bufferp stderr) | ||
| 3047 | (add-function | ||
| 3048 | :after (process-sentinel p) | ||
| 3049 | (lambda (_proc _msg) | ||
| 3050 | (ignore-errors | ||
| 3051 | (while (accept-process-output | ||
| 3052 | (get-buffer-process stderr) 0 nil t)) | ||
| 3053 | (delete-process (get-buffer-process stderr))) | ||
| 3054 | (ignore-errors | ||
| 3055 | (delete-file remote-tmpstderr))))) | ||
| 3056 | ;; Return process. | ||
| 3057 | p))) | ||
| 3058 | |||
| 3059 | ;; Save exit. | ||
| 3060 | (if (string-prefix-p tramp-temp-buffer-name (buffer-name)) | ||
| 3061 | (ignore-errors | ||
| 3062 | (set-process-buffer p nil) | ||
| 3063 | (kill-buffer (current-buffer))) | ||
| 3064 | (set-buffer-modified-p bmp)))))))))))) | ||
| 3065 | 3067 | ||
| 3066 | (defun tramp-sh-get-signal-strings (vec) | 3068 | (defun tramp-sh-get-signal-strings (vec) |
| 3067 | "Strings to return by `process-file' in case of signals." | 3069 | "Strings to return by `process-file' in case of signals." |
| @@ -3242,7 +3244,7 @@ implementation will be used." | |||
| 3242 | ;; because the remote process could have changed them. | 3244 | ;; because the remote process could have changed them. |
| 3243 | (when tmpinput (delete-file tmpinput)) | 3245 | (when tmpinput (delete-file tmpinput)) |
| 3244 | (when process-file-side-effects | 3246 | (when process-file-side-effects |
| 3245 | (tramp-flush-directory-properties v "")) | 3247 | (tramp-flush-directory-properties v "/")) |
| 3246 | 3248 | ||
| 3247 | ;; Return exit status. | 3249 | ;; Return exit status. |
| 3248 | (if (equal ret -1) | 3250 | (if (equal ret -1) |
| @@ -3334,194 +3336,201 @@ implementation will be used." | |||
| 3334 | (start end filename &optional append visit lockname mustbenew) | 3336 | (start end filename &optional append visit lockname mustbenew) |
| 3335 | "Like `write-region' for Tramp files." | 3337 | "Like `write-region' for Tramp files." |
| 3336 | (tramp-skeleton-write-region start end filename append visit lockname mustbenew | 3338 | (tramp-skeleton-write-region start end filename append visit lockname mustbenew |
| 3337 | (if (and (tramp-local-host-p v) | 3339 | ;; If `start' is the empty string, it is likely that a temporary |
| 3338 | ;; `file-writable-p' calls `file-expand-file-name'. We | 3340 | ;; file is created. Do it directly. |
| 3339 | ;; cannot use `tramp-run-real-handler' therefore. | 3341 | (if (and (stringp start) (string-empty-p start)) |
| 3340 | (file-writable-p (file-name-directory localname)) | 3342 | (tramp-send-command |
| 3341 | (or (file-directory-p localname) | 3343 | v (format "echo -n \"\">%s" (tramp-shell-quote-argument localname))) |
| 3342 | (file-writable-p localname))) | 3344 | |
| 3343 | ;; Short track: if we are on the local host, we can run directly. | 3345 | ;; Short track: if we are on the local host, we can run directly. |
| 3344 | (let ((create-lockfiles (not file-locked))) | 3346 | (if (and (tramp-local-host-p v) |
| 3345 | (write-region start end localname append 'no-message lockname)) | 3347 | ;; `file-writable-p' calls `file-expand-file-name'. We |
| 3346 | 3348 | ;; cannot use `tramp-run-real-handler' therefore. | |
| 3347 | (let* ((modes (tramp-default-file-modes | 3349 | (file-writable-p (file-name-directory localname)) |
| 3348 | filename (and (eq mustbenew 'excl) 'nofollow))) | 3350 | (or (file-directory-p localname) |
| 3349 | ;; We use this to save the value of | 3351 | (file-writable-p localname))) |
| 3350 | ;; `last-coding-system-used' after writing the tmp file. | 3352 | (let ((create-lockfiles (not file-locked))) |
| 3351 | ;; At the end of the function, we set | 3353 | (write-region start end localname append 'no-message lockname)) |
| 3352 | ;; `last-coding-system-used' to this saved value. This | 3354 | |
| 3353 | ;; way, any intermediary coding systems used while | 3355 | (let* ((modes (tramp-default-file-modes |
| 3354 | ;; talking to the remote shell or suchlike won't hose | 3356 | filename (and (eq mustbenew 'excl) 'nofollow))) |
| 3355 | ;; this variable. This approach was snarfed from | 3357 | ;; We use this to save the value of |
| 3356 | ;; ange-ftp.el. | 3358 | ;; `last-coding-system-used' after writing the tmp |
| 3357 | coding-system-used | 3359 | ;; file. At the end of the function, we set |
| 3358 | ;; Write region into a tmp file. This isn't really | 3360 | ;; `last-coding-system-used' to this saved value. This |
| 3359 | ;; needed if we use an encoding function, but currently | 3361 | ;; way, any intermediary coding systems used while |
| 3360 | ;; we use it always because this makes the logic simpler. | 3362 | ;; talking to the remote shell or suchlike won't hose |
| 3361 | ;; We must also set `temporary-file-directory', because | 3363 | ;; this variable. This approach was snarfed from |
| 3362 | ;; it could point to a remote directory. | 3364 | ;; ange-ftp.el. |
| 3363 | (temporary-file-directory | 3365 | coding-system-used |
| 3364 | tramp-compat-temporary-file-directory) | 3366 | ;; Write region into a tmp file. This isn't really |
| 3365 | (tmpfile (or tramp-temp-buffer-file-name | 3367 | ;; needed if we use an encoding function, but currently |
| 3366 | (tramp-compat-make-temp-file filename)))) | 3368 | ;; we use it always because this makes the logic |
| 3367 | 3369 | ;; simpler. We must also set | |
| 3368 | ;; If `append' is non-nil, we copy the file locally, and let | 3370 | ;; `temporary-file-directory', because it could point |
| 3369 | ;; the native `write-region' implementation do the job. | 3371 | ;; to a remote directory. |
| 3370 | (when (and append (file-exists-p filename)) | 3372 | (temporary-file-directory |
| 3371 | (copy-file filename tmpfile 'ok)) | 3373 | tramp-compat-temporary-file-directory) |
| 3372 | 3374 | (tmpfile (or tramp-temp-buffer-file-name | |
| 3373 | ;; We say `no-message' here because we don't want the visited | 3375 | (tramp-compat-make-temp-file filename)))) |
| 3374 | ;; file modtime data to be clobbered from the temp file. We | 3376 | |
| 3375 | ;; call `set-visited-file-modtime' ourselves later on. We | 3377 | ;; If `append' is non-nil, we copy the file locally, and let |
| 3376 | ;; must ensure that `file-coding-system-alist' matches | 3378 | ;; the native `write-region' implementation do the job. |
| 3377 | ;; `tmpfile'. | 3379 | (when (and append (file-exists-p filename)) |
| 3378 | (let ((file-coding-system-alist | 3380 | (copy-file filename tmpfile 'ok)) |
| 3379 | (tramp-find-file-name-coding-system-alist filename tmpfile)) | 3381 | |
| 3380 | create-lockfiles) | 3382 | ;; We say `no-message' here because we don't want the |
| 3381 | (condition-case err | 3383 | ;; visited file modtime data to be clobbered from the temp |
| 3382 | (write-region start end tmpfile append 'no-message) | 3384 | ;; file. We call `set-visited-file-modtime' ourselves later |
| 3383 | ((error quit) | 3385 | ;; on. We must ensure that `file-coding-system-alist' |
| 3384 | (setq tramp-temp-buffer-file-name nil) | 3386 | ;; matches `tmpfile'. |
| 3385 | (delete-file tmpfile) | 3387 | (let ((file-coding-system-alist |
| 3386 | (signal (car err) (cdr err)))) | 3388 | (tramp-find-file-name-coding-system-alist filename tmpfile)) |
| 3387 | 3389 | create-lockfiles) | |
| 3388 | ;; Now, `last-coding-system-used' has the right value. | 3390 | (condition-case err |
| 3389 | ;; Remember it. | 3391 | (write-region start end tmpfile append 'no-message) |
| 3390 | (setq coding-system-used last-coding-system-used)) | 3392 | ((error quit) |
| 3391 | 3393 | (setq tramp-temp-buffer-file-name nil) | |
| 3392 | ;; The permissions of the temporary file should be set. If | 3394 | (delete-file tmpfile) |
| 3393 | ;; FILENAME does not exist (eq modes nil) it has been renamed | 3395 | (signal (car err) (cdr err)))) |
| 3394 | ;; to the backup file. This case `save-buffer' handles | 3396 | |
| 3395 | ;; permissions. Ensure that it is still readable. | 3397 | ;; Now, `last-coding-system-used' has the right value. |
| 3396 | (when modes | 3398 | ;; Remember it. |
| 3397 | (set-file-modes tmpfile (logior (or modes 0) #o0400))) | 3399 | (setq coding-system-used last-coding-system-used)) |
| 3398 | 3400 | ||
| 3399 | ;; This is a bit lengthy due to the different methods possible | 3401 | ;; The permissions of the temporary file should be set. If |
| 3400 | ;; for file transfer. First, we check whether the method uses | 3402 | ;; FILENAME does not exist (eq modes nil) it has been |
| 3401 | ;; an scp program. If so, we call it. Otherwise, both | 3403 | ;; renamed to the backup file. This case `save-buffer' |
| 3402 | ;; encoding and decoding command must be specified. However, | 3404 | ;; handles permissions. Ensure that it is still readable. |
| 3403 | ;; if the method _also_ specifies an encoding function, then | 3405 | (when modes |
| 3404 | ;; that is used for encoding the contents of the tmp file. | 3406 | (set-file-modes tmpfile (logior (or modes 0) #o0400))) |
| 3405 | (let* ((size (file-attribute-size (file-attributes tmpfile))) | 3407 | |
| 3406 | (rem-dec (tramp-get-inline-coding v "remote-decoding" size)) | 3408 | ;; This is a bit lengthy due to the different methods |
| 3407 | (loc-enc (tramp-get-inline-coding v "local-encoding" size))) | 3409 | ;; possible for file transfer. First, we check whether the |
| 3408 | (cond | 3410 | ;; method uses an scp program. If so, we call it. |
| 3409 | ;; `copy-file' handles direct copy and out-of-band methods. | 3411 | ;; Otherwise, both encoding and decoding command must be |
| 3410 | ((or (tramp-local-host-p v) | 3412 | ;; specified. However, if the method _also_ specifies an |
| 3411 | (tramp-method-out-of-band-p v size)) | 3413 | ;; encoding function, then that is used for encoding the |
| 3412 | (if (and (not (stringp start)) | 3414 | ;; contents of the tmp file. |
| 3413 | (= (or end (point-max)) (point-max)) | 3415 | (let* ((size (file-attribute-size (file-attributes tmpfile))) |
| 3414 | (= (or start (point-min)) (point-min)) | 3416 | (rem-dec (tramp-get-inline-coding v "remote-decoding" size)) |
| 3415 | (tramp-get-method-parameter | 3417 | (loc-enc (tramp-get-inline-coding v "local-encoding" size))) |
| 3416 | v 'tramp-copy-keep-tmpfile)) | 3418 | (cond |
| 3417 | (progn | 3419 | ;; `copy-file' handles direct copy and out-of-band methods. |
| 3418 | (setq tramp-temp-buffer-file-name tmpfile) | 3420 | ((or (tramp-local-host-p v) |
| 3419 | (condition-case err | 3421 | (tramp-method-out-of-band-p v size)) |
| 3420 | ;; We keep the local file for performance | 3422 | (if (and (not (stringp start)) |
| 3421 | ;; reasons, useful for "rsync". | 3423 | (= (or end (point-max)) (point-max)) |
| 3422 | (copy-file tmpfile filename t) | 3424 | (= (or start (point-min)) (point-min)) |
| 3423 | ((error quit) | 3425 | (tramp-get-method-parameter |
| 3424 | (setq tramp-temp-buffer-file-name nil) | 3426 | v 'tramp-copy-keep-tmpfile)) |
| 3425 | (delete-file tmpfile) | 3427 | (progn |
| 3426 | (signal (car err) (cdr err))))) | 3428 | (setq tramp-temp-buffer-file-name tmpfile) |
| 3427 | (setq tramp-temp-buffer-file-name nil) | 3429 | (condition-case err |
| 3428 | ;; Don't rename, in order to keep context in SELinux. | 3430 | ;; We keep the local file for performance |
| 3431 | ;; reasons, useful for "rsync". | ||
| 3432 | (copy-file tmpfile filename t) | ||
| 3433 | ((error quit) | ||
| 3434 | (setq tramp-temp-buffer-file-name nil) | ||
| 3435 | (delete-file tmpfile) | ||
| 3436 | (signal (car err) (cdr err))))) | ||
| 3437 | (setq tramp-temp-buffer-file-name nil) | ||
| 3438 | ;; Don't rename, in order to keep context in SELinux. | ||
| 3439 | (unwind-protect | ||
| 3440 | (copy-file tmpfile filename t) | ||
| 3441 | (delete-file tmpfile)))) | ||
| 3442 | |||
| 3443 | ;; Use inline file transfer. | ||
| 3444 | (rem-dec | ||
| 3445 | ;; Encode tmpfile. | ||
| 3429 | (unwind-protect | 3446 | (unwind-protect |
| 3430 | (copy-file tmpfile filename t) | 3447 | (with-temp-buffer |
| 3431 | (delete-file tmpfile)))) | 3448 | (set-buffer-multibyte nil) |
| 3432 | 3449 | ;; Use encoding function or command. | |
| 3433 | ;; Use inline file transfer. | 3450 | (with-tramp-progress-reporter |
| 3434 | (rem-dec | 3451 | v 3 (format-message |
| 3435 | ;; Encode tmpfile. | 3452 | "Encoding local file `%s' using `%s'" |
| 3436 | (unwind-protect | 3453 | tmpfile loc-enc) |
| 3437 | (with-temp-buffer | 3454 | (if (functionp loc-enc) |
| 3438 | (set-buffer-multibyte nil) | 3455 | ;; The following `let' is a workaround for |
| 3439 | ;; Use encoding function or command. | 3456 | ;; the base64.el that comes with pgnus-0.84. |
| 3440 | (with-tramp-progress-reporter | 3457 | ;; If both of the following conditions are |
| 3441 | v 3 (format-message | 3458 | ;; satisfied, it tries to write to a local |
| 3442 | "Encoding local file `%s' using `%s'" | 3459 | ;; file in default-directory, but at this |
| 3443 | tmpfile loc-enc) | 3460 | ;; point, default-directory is remote. |
| 3444 | (if (functionp loc-enc) | 3461 | ;; (`call-process-region' can't write to |
| 3445 | ;; The following `let' is a workaround for the | 3462 | ;; remote files, it seems.) The file in |
| 3446 | ;; base64.el that comes with pgnus-0.84. If | 3463 | ;; question is a tmp file anyway. |
| 3447 | ;; both of the following conditions are | 3464 | (let ((coding-system-for-read 'binary) |
| 3448 | ;; satisfied, it tries to write to a local | 3465 | (default-directory |
| 3449 | ;; file in default-directory, but at this | 3466 | tramp-compat-temporary-file-directory)) |
| 3450 | ;; point, default-directory is remote. | 3467 | (insert-file-contents-literally tmpfile) |
| 3451 | ;; (`call-process-region' can't write to | 3468 | (funcall loc-enc (point-min) (point-max))) |
| 3452 | ;; remote files, it seems.) The file in | 3469 | |
| 3453 | ;; question is a tmp file anyway. | 3470 | (unless (zerop (tramp-call-local-coding-command |
| 3454 | (let ((coding-system-for-read 'binary) | 3471 | loc-enc tmpfile t)) |
| 3455 | (default-directory | 3472 | (tramp-error |
| 3456 | tramp-compat-temporary-file-directory)) | 3473 | v 'file-error |
| 3457 | (insert-file-contents-literally tmpfile) | 3474 | (concat "Cannot write to `%s', " |
| 3458 | (funcall loc-enc (point-min) (point-max))) | 3475 | "local encoding command `%s' failed") |
| 3459 | 3476 | filename loc-enc)))) | |
| 3460 | (unless (zerop (tramp-call-local-coding-command | 3477 | |
| 3461 | loc-enc tmpfile t)) | 3478 | ;; Send buffer into remote decoding command which |
| 3462 | (tramp-error | 3479 | ;; writes to remote file. Because this happens on |
| 3463 | v 'file-error | 3480 | ;; the remote host, we cannot use the function. |
| 3464 | (concat "Cannot write to `%s', " | 3481 | (with-tramp-progress-reporter |
| 3465 | "local encoding command `%s' failed") | 3482 | v 3 (format-message |
| 3466 | filename loc-enc)))) | 3483 | "Decoding remote file `%s' using `%s'" |
| 3467 | 3484 | filename rem-dec) | |
| 3468 | ;; Send buffer into remote decoding command which | 3485 | (goto-char (point-max)) |
| 3469 | ;; writes to remote file. Because this happens on | 3486 | (unless (bolp) (newline)) |
| 3470 | ;; the remote host, we cannot use the function. | 3487 | (tramp-barf-unless-okay |
| 3471 | (with-tramp-progress-reporter | 3488 | v (format |
| 3472 | v 3 (format-message | 3489 | (concat rem-dec " <<'%s'\n%s%s") |
| 3473 | "Decoding remote file `%s' using `%s'" | 3490 | (tramp-shell-quote-argument localname) |
| 3474 | filename rem-dec) | 3491 | tramp-end-of-heredoc |
| 3475 | (goto-char (point-max)) | 3492 | (buffer-string) |
| 3476 | (unless (bolp) (newline)) | 3493 | tramp-end-of-heredoc) |
| 3477 | (tramp-barf-unless-okay | 3494 | "Couldn't write region to `%s', decode using `%s' failed" |
| 3478 | v | 3495 | filename rem-dec) |
| 3479 | (format | 3496 | ;; When `file-precious-flag' is set, the region |
| 3480 | (concat rem-dec " <<'%s'\n%s%s") | 3497 | ;; is written to a temporary file. Check that |
| 3481 | (tramp-shell-quote-argument localname) | 3498 | ;; the checksum is equal to that from the local |
| 3482 | tramp-end-of-heredoc | 3499 | ;; tmpfile. |
| 3483 | (buffer-string) | 3500 | (when file-precious-flag |
| 3484 | tramp-end-of-heredoc) | 3501 | (erase-buffer) |
| 3485 | "Couldn't write region to `%s', decode using `%s' failed" | 3502 | (and |
| 3486 | filename rem-dec) | 3503 | ;; cksum runs locally, if possible. |
| 3487 | ;; When `file-precious-flag' is set, the region is | 3504 | (zerop (tramp-call-process v "cksum" tmpfile t)) |
| 3488 | ;; written to a temporary file. Check that the | 3505 | ;; cksum runs remotely. |
| 3489 | ;; checksum is equal to that from the local tmpfile. | 3506 | (tramp-send-command-and-check |
| 3490 | (when file-precious-flag | 3507 | v (format |
| 3491 | (erase-buffer) | 3508 | "cksum <%s" (tramp-shell-quote-argument localname))) |
| 3492 | (and | 3509 | ;; ... they are different. |
| 3493 | ;; cksum runs locally, if possible. | 3510 | (not |
| 3494 | (zerop (tramp-call-process v "cksum" tmpfile t)) | 3511 | (string-equal |
| 3495 | ;; cksum runs remotely. | 3512 | (buffer-string) |
| 3496 | (tramp-send-command-and-check | 3513 | (tramp-get-buffer-string (tramp-get-buffer v)))) |
| 3497 | v | 3514 | (tramp-error |
| 3498 | (format | 3515 | v 'file-error |
| 3499 | "cksum <%s" | 3516 | (concat "Couldn't write region to `%s'," |
| 3500 | (tramp-shell-quote-argument localname))) | 3517 | " decode using `%s' failed") |
| 3501 | ;; ... they are different. | 3518 | filename rem-dec))))) |
| 3502 | (not | 3519 | |
| 3503 | (string-equal | 3520 | ;; Save exit. |
| 3504 | (buffer-string) | 3521 | (delete-file tmpfile))) |
| 3505 | (tramp-get-buffer-string (tramp-get-buffer v)))) | ||
| 3506 | (tramp-error | ||
| 3507 | v 'file-error | ||
| 3508 | "Couldn't write region to `%s', decode using `%s' failed" | ||
| 3509 | filename rem-dec))))) | ||
| 3510 | |||
| 3511 | ;; Save exit. | ||
| 3512 | (delete-file tmpfile))) | ||
| 3513 | |||
| 3514 | ;; That's not expected. | ||
| 3515 | (t | ||
| 3516 | (tramp-error | ||
| 3517 | v 'file-error | ||
| 3518 | (concat "Method `%s' should specify both encoding and " | ||
| 3519 | "decoding command or an scp program") | ||
| 3520 | method)))) | ||
| 3521 | 3522 | ||
| 3522 | ;; Make `last-coding-system-used' have the right value. | 3523 | ;; That's not expected. |
| 3523 | (when coding-system-used | 3524 | (t |
| 3524 | (setq last-coding-system-used coding-system-used)))))) | 3525 | (tramp-error |
| 3526 | v 'file-error | ||
| 3527 | (concat "Method `%s' should specify both encoding and " | ||
| 3528 | "decoding command or an scp program") | ||
| 3529 | method)))) | ||
| 3530 | |||
| 3531 | ;; Make `last-coding-system-used' have the right value. | ||
| 3532 | (when coding-system-used | ||
| 3533 | (setq last-coding-system-used coding-system-used))))))) | ||
| 3525 | 3534 | ||
| 3526 | (defvar tramp-vc-registered-file-names nil | 3535 | (defvar tramp-vc-registered-file-names nil |
| 3527 | "List used to collect file names, which are checked during `vc-registered'.") | 3536 | "List used to collect file names, which are checked during `vc-registered'.") |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 29abdb575d3..a81a8f13636 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -523,49 +523,49 @@ arguments to pass to the OPERATION." | |||
| 523 | "tar qx -"))))) | 523 | "tar qx -"))))) |
| 524 | 524 | ||
| 525 | (unwind-protect | 525 | (unwind-protect |
| 526 | (with-tramp-saved-connection-property v "process-name" | 526 | (with-tramp-saved-connection-properties |
| 527 | (with-tramp-saved-connection-property v "process-buffer" | 527 | v '("process-name" "process-buffer") |
| 528 | (with-temp-buffer | 528 | (with-temp-buffer |
| 529 | ;; Set the transfer process properties. | 529 | ;; Set the transfer process properties. |
| 530 | (tramp-set-connection-property | 530 | (tramp-set-connection-property |
| 531 | v "process-name" (buffer-name (current-buffer))) | 531 | v "process-name" (buffer-name (current-buffer))) |
| 532 | (tramp-set-connection-property | 532 | (tramp-set-connection-property |
| 533 | v "process-buffer" (current-buffer)) | 533 | v "process-buffer" (current-buffer)) |
| 534 | 534 | ||
| 535 | (when t1 | 535 | (when t1 |
| 536 | ;; The smbclient tar command creates | 536 | ;; The smbclient tar command creates |
| 537 | ;; always complete paths. We must | 537 | ;; always complete paths. We must emulate |
| 538 | ;; emulate the directory structure, and | 538 | ;; the directory structure, and symlink to |
| 539 | ;; symlink to the real target. | 539 | ;; the real target. |
| 540 | (make-directory | 540 | (make-directory |
| 541 | (expand-file-name | 541 | (expand-file-name |
| 542 | ".." (concat tmpdir localname)) | 542 | ".." (concat tmpdir localname)) |
| 543 | 'parents) | 543 | 'parents) |
| 544 | (make-symbolic-link | 544 | (make-symbolic-link |
| 545 | newname | 545 | newname |
| 546 | (directory-file-name (concat tmpdir localname)))) | 546 | (directory-file-name (concat tmpdir localname)))) |
| 547 | 547 | ||
| 548 | ;; Use an asynchronous processes. By | 548 | ;; Use an asynchronous processes. By this, |
| 549 | ;; this, password can be handled. | 549 | ;; password can be handled. |
| 550 | (let* ((default-directory tmpdir) | 550 | (let* ((default-directory tmpdir) |
| 551 | (p (apply | 551 | (p (apply |
| 552 | #'start-process | 552 | #'start-process |
| 553 | (tramp-get-connection-name v) | 553 | (tramp-get-connection-name v) |
| 554 | (tramp-get-connection-buffer v) | 554 | (tramp-get-connection-buffer v) |
| 555 | tramp-smb-program args))) | 555 | tramp-smb-program args))) |
| 556 | 556 | ||
| 557 | (tramp-message | 557 | (tramp-message |
| 558 | v 6 "%s" (string-join (process-command p) " ")) | 558 | v 6 "%s" (string-join (process-command p) " ")) |
| 559 | (process-put p 'vector v) | 559 | (process-put p 'vector v) |
| 560 | (process-put | 560 | (process-put |
| 561 | p 'adjust-window-size-function #'ignore) | 561 | p 'adjust-window-size-function #'ignore) |
| 562 | (set-process-query-on-exit-flag p nil) | 562 | (set-process-query-on-exit-flag p nil) |
| 563 | (tramp-process-actions | 563 | (tramp-process-actions |
| 564 | p v nil tramp-smb-actions-with-tar) | 564 | p v nil tramp-smb-actions-with-tar) |
| 565 | 565 | ||
| 566 | (while (process-live-p p) | 566 | (while (process-live-p p) |
| 567 | (sleep-for 0.1)) | 567 | (sleep-for 0.1)) |
| 568 | (tramp-message v 6 "\n%s" (buffer-string)))))) | 568 | (tramp-message v 6 "\n%s" (buffer-string))))) |
| 569 | 569 | ||
| 570 | ;; Save exit. | 570 | ;; Save exit. |
| 571 | (when t1 (delete-directory tmpdir 'recursive)))) | 571 | (when t1 (delete-directory tmpdir 'recursive)))) |
| @@ -751,6 +751,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 751 | localname | 751 | localname |
| 752 | (tramp-run-real-handler #'expand-file-name (list localname))))))) | 752 | (tramp-run-real-handler #'expand-file-name (list localname))))))) |
| 753 | 753 | ||
| 754 | (defun tramp-smb-remote-acl-p (_vec) | ||
| 755 | "Check, whether ACL is enabled on the remote host." | ||
| 756 | (and (stringp tramp-smb-acl-program) (executable-find tramp-smb-acl-program))) | ||
| 757 | |||
| 754 | (defun tramp-smb-action-get-acl (proc vec) | 758 | (defun tramp-smb-action-get-acl (proc vec) |
| 755 | "Read ACL data from connection buffer." | 759 | "Read ACL data from connection buffer." |
| 756 | (unless (process-live-p proc) | 760 | (unless (process-live-p proc) |
| @@ -774,7 +778,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 774 | (ignore-errors | 778 | (ignore-errors |
| 775 | (with-parsed-tramp-file-name filename nil | 779 | (with-parsed-tramp-file-name filename nil |
| 776 | (with-tramp-file-property v localname "file-acl" | 780 | (with-tramp-file-property v localname "file-acl" |
| 777 | (when (executable-find tramp-smb-acl-program) | 781 | (when (tramp-smb-remote-acl-p v) |
| 778 | (let* ((share (tramp-smb-get-share v)) | 782 | (let* ((share (tramp-smb-get-share v)) |
| 779 | (localname (tramp-compat-string-replace | 783 | (localname (tramp-compat-string-replace |
| 780 | "\\" "/" (tramp-smb-get-localname v))) | 784 | "\\" "/" (tramp-smb-get-localname v))) |
| @@ -799,31 +803,31 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 799 | (concat "2>" (tramp-get-remote-null-device v))))) | 803 | (concat "2>" (tramp-get-remote-null-device v))))) |
| 800 | 804 | ||
| 801 | (unwind-protect | 805 | (unwind-protect |
| 802 | (with-tramp-saved-connection-property v "process-name" | 806 | (with-tramp-saved-connection-properties |
| 803 | (with-tramp-saved-connection-property v "process-buffer" | 807 | v '("process-name" "process-buffer") |
| 804 | (with-temp-buffer | 808 | (with-temp-buffer |
| 805 | ;; Set the transfer process properties. | 809 | ;; Set the transfer process properties. |
| 806 | (tramp-set-connection-property | 810 | (tramp-set-connection-property |
| 807 | v "process-name" (buffer-name (current-buffer))) | 811 | v "process-name" (buffer-name (current-buffer))) |
| 808 | (tramp-set-connection-property | 812 | (tramp-set-connection-property |
| 809 | v "process-buffer" (current-buffer)) | 813 | v "process-buffer" (current-buffer)) |
| 810 | 814 | ||
| 811 | ;; Use an asynchronous process. By this, | 815 | ;; Use an asynchronous process. By this, password |
| 812 | ;; password can be handled. | 816 | ;; can be handled. |
| 813 | (let ((p (apply | 817 | (let ((p (apply |
| 814 | #'start-process | 818 | #'start-process |
| 815 | (tramp-get-connection-name v) | 819 | (tramp-get-connection-name v) |
| 816 | (tramp-get-connection-buffer v) | 820 | (tramp-get-connection-buffer v) |
| 817 | tramp-smb-acl-program args))) | 821 | tramp-smb-acl-program args))) |
| 818 | 822 | ||
| 819 | (tramp-message | 823 | (tramp-message |
| 820 | v 6 "%s" (string-join (process-command p) " ")) | 824 | v 6 "%s" (string-join (process-command p) " ")) |
| 821 | (process-put p 'vector v) | 825 | (process-put p 'vector v) |
| 822 | (process-put p 'adjust-window-size-function #'ignore) | 826 | (process-put p 'adjust-window-size-function #'ignore) |
| 823 | (set-process-query-on-exit-flag p nil) | 827 | (set-process-query-on-exit-flag p nil) |
| 824 | (tramp-process-actions p v nil tramp-smb-actions-get-acl) | 828 | (tramp-process-actions p v nil tramp-smb-actions-get-acl) |
| 825 | (when (> (point-max) (point-min)) | 829 | (when (> (point-max) (point-min)) |
| 826 | (substring-no-properties (buffer-string)))))))))))))) | 830 | (substring-no-properties (buffer-string))))))))))))) |
| 827 | 831 | ||
| 828 | (defun tramp-smb-handle-file-attributes (filename &optional id-format) | 832 | (defun tramp-smb-handle-file-attributes (filename &optional id-format) |
| 829 | "Like `file-attributes' for Tramp files." | 833 | "Like `file-attributes' for Tramp files." |
| @@ -1311,32 +1315,32 @@ component is used as the target of the symlink." | |||
| 1311 | 1315 | ||
| 1312 | ;; Call it. | 1316 | ;; Call it. |
| 1313 | (condition-case nil | 1317 | (condition-case nil |
| 1314 | (with-tramp-saved-connection-property v "process-name" | 1318 | (with-tramp-saved-connection-properties |
| 1315 | (with-tramp-saved-connection-property v "process-buffer" | 1319 | v '("process-name" "process-buffer") |
| 1316 | ;; Set the new process properties. | 1320 | ;; Set the new process properties. |
| 1317 | (tramp-set-connection-property v "process-name" name1) | 1321 | (tramp-set-connection-property v "process-name" name1) |
| 1318 | (tramp-set-connection-property | 1322 | (tramp-set-connection-property |
| 1319 | v "process-buffer" | 1323 | v "process-buffer" |
| 1320 | (or outbuf (generate-new-buffer tramp-temp-buffer-name))) | 1324 | (or outbuf (generate-new-buffer tramp-temp-buffer-name))) |
| 1321 | (with-current-buffer (tramp-get-connection-buffer v) | 1325 | (with-current-buffer (tramp-get-connection-buffer v) |
| 1322 | ;; Preserve buffer contents. | 1326 | ;; Preserve buffer contents. |
| 1323 | (narrow-to-region (point-max) (point-max)) | 1327 | (narrow-to-region (point-max) (point-max)) |
| 1324 | (tramp-smb-call-winexe v) | 1328 | (tramp-smb-call-winexe v) |
| 1325 | (when (tramp-smb-get-share v) | 1329 | (when (tramp-smb-get-share v) |
| 1326 | (tramp-smb-send-command | 1330 | (tramp-smb-send-command |
| 1327 | v (format "cd //%s%s" host | 1331 | v (format "cd //%s%s" host |
| 1328 | (tramp-smb-shell-quote-argument | 1332 | (tramp-smb-shell-quote-argument |
| 1329 | (file-name-directory localname))))) | 1333 | (file-name-directory localname))))) |
| 1330 | (tramp-smb-send-command v command) | 1334 | (tramp-smb-send-command v command) |
| 1331 | ;; Preserve command output. | 1335 | ;; Preserve command output. |
| 1332 | (narrow-to-region (point-max) (point-max)) | 1336 | (narrow-to-region (point-max) (point-max)) |
| 1333 | (let ((p (tramp-get-connection-process v))) | 1337 | (let ((p (tramp-get-connection-process v))) |
| 1334 | (tramp-smb-send-command v "exit $lasterrorcode") | 1338 | (tramp-smb-send-command v "exit $lasterrorcode") |
| 1335 | (while (process-live-p p) | 1339 | (while (process-live-p p) |
| 1336 | (sleep-for 0.1) | 1340 | (sleep-for 0.1) |
| 1337 | (setq ret (process-exit-status p)))) | 1341 | (setq ret (process-exit-status p)))) |
| 1338 | (delete-region (point-min) (point-max)) | 1342 | (delete-region (point-min) (point-max)) |
| 1339 | (widen)))) | 1343 | (widen))) |
| 1340 | 1344 | ||
| 1341 | ;; When the user did interrupt, we should do it also. We use | 1345 | ;; When the user did interrupt, we should do it also. We use |
| 1342 | ;; return code -1 as marker. | 1346 | ;; return code -1 as marker. |
| @@ -1356,7 +1360,7 @@ component is used as the target of the symlink." | |||
| 1356 | (unless outbuf | 1360 | (unless outbuf |
| 1357 | (kill-buffer (tramp-get-connection-property v "process-buffer"))) | 1361 | (kill-buffer (tramp-get-connection-property v "process-buffer"))) |
| 1358 | (when process-file-side-effects | 1362 | (when process-file-side-effects |
| 1359 | (tramp-flush-directory-properties v "")) | 1363 | (tramp-flush-directory-properties v "/")) |
| 1360 | 1364 | ||
| 1361 | ;; Return exit status. | 1365 | ;; Return exit status. |
| 1362 | (if (equal ret -1) | 1366 | (if (equal ret -1) |
| @@ -1427,7 +1431,7 @@ component is used as the target of the symlink." | |||
| 1427 | (with-parsed-tramp-file-name filename nil | 1431 | (with-parsed-tramp-file-name filename nil |
| 1428 | (tramp-flush-file-property v localname "file-acl") | 1432 | (tramp-flush-file-property v localname "file-acl") |
| 1429 | 1433 | ||
| 1430 | (when (and (stringp acl-string) (executable-find tramp-smb-acl-program)) | 1434 | (when (and (stringp acl-string) (tramp-smb-remote-acl-p v)) |
| 1431 | (let* ((share (tramp-smb-get-share v)) | 1435 | (let* ((share (tramp-smb-get-share v)) |
| 1432 | (localname (tramp-compat-string-replace | 1436 | (localname (tramp-compat-string-replace |
| 1433 | "\\" "/" (tramp-smb-get-localname v))) | 1437 | "\\" "/" (tramp-smb-get-localname v))) |
| @@ -1455,52 +1459,50 @@ component is used as the target of the symlink." | |||
| 1455 | "||" "echo" "tramp_exit_status" "1"))) | 1459 | "||" "echo" "tramp_exit_status" "1"))) |
| 1456 | 1460 | ||
| 1457 | (unwind-protect | 1461 | (unwind-protect |
| 1458 | (with-tramp-saved-connection-property v "process-name" | 1462 | (with-tramp-saved-connection-properties |
| 1459 | (with-tramp-saved-connection-property v "process-buffer" | 1463 | v '("process-name" "process-buffer") |
| 1460 | (with-temp-buffer | 1464 | (with-temp-buffer |
| 1461 | ;; Set the transfer process properties. | 1465 | ;; Set the transfer process properties. |
| 1462 | (tramp-set-connection-property | 1466 | (tramp-set-connection-property |
| 1463 | v "process-name" (buffer-name (current-buffer))) | 1467 | v "process-name" (buffer-name (current-buffer))) |
| 1464 | (tramp-set-connection-property | 1468 | (tramp-set-connection-property |
| 1465 | v "process-buffer" (current-buffer)) | 1469 | v "process-buffer" (current-buffer)) |
| 1466 | 1470 | ||
| 1467 | ;; Use an asynchronous process. By this, password | 1471 | ;; Use an asynchronous process. By this, password |
| 1468 | ;; can be handled. | 1472 | ;; can be handled. |
| 1469 | (let ((p (apply | 1473 | (let ((p (apply |
| 1470 | #'start-process | 1474 | #'start-process |
| 1471 | (tramp-get-connection-name v) | 1475 | (tramp-get-connection-name v) |
| 1472 | (tramp-get-connection-buffer v) | 1476 | (tramp-get-connection-buffer v) |
| 1473 | tramp-smb-acl-program args))) | 1477 | tramp-smb-acl-program args))) |
| 1474 | 1478 | ||
| 1475 | (tramp-message | 1479 | (tramp-message |
| 1476 | v 6 "%s" (string-join (process-command p) " ")) | 1480 | v 6 "%s" (string-join (process-command p) " ")) |
| 1477 | (process-put p 'vector v) | 1481 | (process-put p 'vector v) |
| 1478 | (process-put p 'adjust-window-size-function #'ignore) | 1482 | (process-put p 'adjust-window-size-function #'ignore) |
| 1479 | (set-process-query-on-exit-flag p nil) | 1483 | (set-process-query-on-exit-flag p nil) |
| 1480 | (tramp-process-actions p v nil tramp-smb-actions-set-acl) | 1484 | (tramp-process-actions p v nil tramp-smb-actions-set-acl) |
| 1481 | ;; This is meant for traces, and returning from | 1485 | ;; This is meant for traces, and returning from |
| 1482 | ;; the function. No error is propagated | 1486 | ;; the function. No error is propagated outside, |
| 1483 | ;; outside, due to the `ignore-errors' closure. | 1487 | ;; due to the `ignore-errors' closure. |
| 1484 | (unless | 1488 | (unless |
| 1485 | (tramp-search-regexp "tramp_exit_status [[:digit:]]+") | 1489 | (tramp-search-regexp "tramp_exit_status [[:digit:]]+") |
| 1486 | (tramp-error | 1490 | (tramp-error |
| 1487 | v 'file-error | 1491 | v 'file-error |
| 1488 | "Couldn't find exit status of `%s'" | 1492 | "Couldn't find exit status of `%s'" |
| 1489 | tramp-smb-acl-program)) | 1493 | tramp-smb-acl-program)) |
| 1490 | (skip-chars-forward "^ ") | 1494 | (skip-chars-forward "^ ") |
| 1491 | (when (zerop (read (current-buffer))) | 1495 | (when (zerop (read (current-buffer))) |
| 1492 | ;; Success. | 1496 | ;; Success. |
| 1493 | (tramp-set-file-property | 1497 | (tramp-set-file-property v localname "file-acl" acl-string) |
| 1494 | v localname "file-acl" acl-string) | 1498 | t)))))))))) |
| 1495 | t))))))))))) | ||
| 1496 | 1499 | ||
| 1497 | (defun tramp-smb-handle-set-file-modes (filename mode &optional flag) | 1500 | (defun tramp-smb-handle-set-file-modes (filename mode &optional flag) |
| 1498 | "Like `set-file-modes' for Tramp files." | 1501 | "Like `set-file-modes' for Tramp files." |
| 1499 | (with-parsed-tramp-file-name filename nil | 1502 | ;; smbclient chmod does not support nofollow. |
| 1500 | ;; smbclient chmod does not support nofollow. | 1503 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) |
| 1501 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) | 1504 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 1502 | (when (tramp-smb-get-cifs-capabilities v) | 1505 | (when (tramp-smb-get-cifs-capabilities v) |
| 1503 | (tramp-flush-file-properties v localname) | ||
| 1504 | (unless (tramp-smb-send-command | 1506 | (unless (tramp-smb-send-command |
| 1505 | v | 1507 | v |
| 1506 | (format "chmod %s %o" (tramp-smb-shell-quote-localname v) mode)) | 1508 | (format "chmod %s %o" (tramp-smb-shell-quote-localname v) mode)) |
| @@ -1524,38 +1526,38 @@ component is used as the target of the symlink." | |||
| 1524 | (i 0) | 1526 | (i 0) |
| 1525 | p) | 1527 | p) |
| 1526 | (unwind-protect | 1528 | (unwind-protect |
| 1527 | (with-tramp-saved-connection-property v "process-name" | 1529 | (with-tramp-saved-connection-properties |
| 1528 | (with-tramp-saved-connection-property v "process-buffer" | 1530 | v '("process-name" "process-buffer") |
| 1529 | (save-excursion | 1531 | (save-excursion |
| 1530 | (save-restriction | 1532 | (save-restriction |
| 1531 | (while (get-process name1) | 1533 | (while (get-process name1) |
| 1532 | ;; NAME must be unique as process name. | 1534 | ;; NAME must be unique as process name. |
| 1533 | (setq i (1+ i) | 1535 | (setq i (1+ i) |
| 1534 | name1 (format "%s<%d>" name i))) | 1536 | name1 (format "%s<%d>" name i))) |
| 1535 | ;; Set the new process properties. | 1537 | ;; Set the new process properties. |
| 1536 | (tramp-set-connection-property v "process-name" name1) | 1538 | (tramp-set-connection-property v "process-name" name1) |
| 1537 | (tramp-set-connection-property v "process-buffer" buffer) | 1539 | (tramp-set-connection-property v "process-buffer" buffer) |
| 1538 | ;; Activate narrowing in order to save BUFFER contents. | 1540 | ;; Activate narrowing in order to save BUFFER contents. |
| 1539 | (with-current-buffer (tramp-get-connection-buffer v) | 1541 | (with-current-buffer (tramp-get-connection-buffer v) |
| 1540 | (let ((buffer-undo-list t)) | 1542 | (let ((buffer-undo-list t)) |
| 1541 | (narrow-to-region (point-max) (point-max)) | 1543 | (narrow-to-region (point-max) (point-max)) |
| 1542 | (tramp-smb-call-winexe v) | 1544 | (tramp-smb-call-winexe v) |
| 1543 | (when (tramp-smb-get-share v) | 1545 | (when (tramp-smb-get-share v) |
| 1544 | (tramp-smb-send-command | 1546 | (tramp-smb-send-command |
| 1545 | v (format | 1547 | v (format |
| 1546 | "cd //%s%s" | 1548 | "cd //%s%s" |
| 1547 | host | 1549 | host |
| 1548 | (tramp-smb-shell-quote-argument | 1550 | (tramp-smb-shell-quote-argument |
| 1549 | (file-name-directory localname))))) | 1551 | (file-name-directory localname))))) |
| 1550 | (tramp-message v 6 "(%s); exit" command) | 1552 | (tramp-message v 6 "(%s); exit" command) |
| 1551 | (tramp-send-string v command))) | 1553 | (tramp-send-string v command))) |
| 1552 | (setq p (tramp-get-connection-process v)) | 1554 | (setq p (tramp-get-connection-process v)) |
| 1553 | (when program | 1555 | (when program |
| 1554 | (process-put p 'remote-command (cons program args)) | 1556 | (process-put p 'remote-command (cons program args)) |
| 1555 | (tramp-set-connection-property | 1557 | (tramp-set-connection-property |
| 1556 | p "remote-command" (cons program args))) | 1558 | p "remote-command" (cons program args))) |
| 1557 | ;; Return value. | 1559 | ;; Return value. |
| 1558 | p)))) | 1560 | p))) |
| 1559 | 1561 | ||
| 1560 | ;; Save exit. | 1562 | ;; Save exit. |
| 1561 | ;; FIXME: Does `tramp-get-connection-buffer' return the proper value? | 1563 | ;; FIXME: Does `tramp-get-connection-buffer' return the proper value? |
| @@ -1933,7 +1935,7 @@ If ARGUMENT is non-nil, use it as argument for | |||
| 1933 | tramp-smb-version | 1935 | tramp-smb-version |
| 1934 | (tramp-get-connection-property | 1936 | (tramp-get-connection-property |
| 1935 | vec "smbclient-version" tramp-smb-version)) | 1937 | vec "smbclient-version" tramp-smb-version)) |
| 1936 | (tramp-flush-directory-properties vec "") | 1938 | (tramp-flush-directory-properties vec "/") |
| 1937 | (tramp-flush-connection-properties vec)) | 1939 | (tramp-flush-connection-properties vec)) |
| 1938 | 1940 | ||
| 1939 | (tramp-set-connection-property | 1941 | (tramp-set-connection-property |
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index d7c918fbc83..a9225db434e 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el | |||
| @@ -333,7 +333,7 @@ arguments to pass to the OPERATION." | |||
| 333 | ;; them. | 333 | ;; them. |
| 334 | (when tmpinput (delete-file tmpinput)) | 334 | (when tmpinput (delete-file tmpinput)) |
| 335 | (when process-file-side-effects | 335 | (when process-file-side-effects |
| 336 | (tramp-flush-directory-properties v "")))))) | 336 | (tramp-flush-directory-properties v "/")))))) |
| 337 | 337 | ||
| 338 | (defun tramp-sshfs-handle-rename-file | 338 | (defun tramp-sshfs-handle-rename-file |
| 339 | (filename newname &optional ok-if-already-exists) | 339 | (filename newname &optional ok-if-already-exists) |
| @@ -355,18 +355,15 @@ arguments to pass to the OPERATION." | |||
| 355 | 355 | ||
| 356 | (defun tramp-sshfs-handle-set-file-modes (filename mode &optional flag) | 356 | (defun tramp-sshfs-handle-set-file-modes (filename mode &optional flag) |
| 357 | "Like `set-file-modes' for Tramp files." | 357 | "Like `set-file-modes' for Tramp files." |
| 358 | (with-parsed-tramp-file-name filename nil | 358 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) |
| 359 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) | 359 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 360 | (tramp-flush-file-properties v localname) | ||
| 361 | (tramp-compat-set-file-modes | 360 | (tramp-compat-set-file-modes |
| 362 | (tramp-fuse-local-file-name filename) mode flag)))) | 361 | (tramp-fuse-local-file-name filename) mode flag)))) |
| 363 | 362 | ||
| 364 | (defun tramp-sshfs-handle-set-file-times (filename &optional timestamp flag) | 363 | (defun tramp-sshfs-handle-set-file-times (filename &optional timestamp flag) |
| 365 | "Like `set-file-times' for Tramp files." | 364 | "Like `set-file-times' for Tramp files." |
| 366 | (or (file-exists-p filename) (write-region "" nil filename nil 0)) | 365 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) |
| 367 | (with-parsed-tramp-file-name filename nil | 366 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 368 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) | ||
| 369 | (tramp-flush-file-properties v localname) | ||
| 370 | (tramp-compat-set-file-times | 367 | (tramp-compat-set-file-times |
| 371 | (tramp-fuse-local-file-name filename) timestamp flag)))) | 368 | (tramp-fuse-local-file-name filename) timestamp flag)))) |
| 372 | 369 | ||
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 5ec68e904e7..3564a1b7b44 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el | |||
| @@ -484,10 +484,9 @@ the result will be a local, non-Tramp, file name." | |||
| 484 | 484 | ||
| 485 | (defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag) | 485 | (defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag) |
| 486 | "Like `set-file-modes' for Tramp files." | 486 | "Like `set-file-modes' for Tramp files." |
| 487 | (with-parsed-tramp-file-name filename nil | 487 | ;; It is unlikely that "chmod -h" works. |
| 488 | ;; It is unlikely that "chmod -h" works. | 488 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) |
| 489 | (unless (and (eq flag 'nofollow) (file-symlink-p filename)) | 489 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 490 | (tramp-flush-file-properties v localname) | ||
| 491 | (unless (tramp-sudoedit-send-command | 490 | (unless (tramp-sudoedit-send-command |
| 492 | v "chmod" (format "%o" mode) | 491 | v "chmod" (format "%o" mode) |
| 493 | (tramp-compat-file-name-unquote localname)) | 492 | (tramp-compat-file-name-unquote localname)) |
| @@ -542,8 +541,7 @@ the result will be a local, non-Tramp, file name." | |||
| 542 | 541 | ||
| 543 | (defun tramp-sudoedit-handle-set-file-times (filename &optional time flag) | 542 | (defun tramp-sudoedit-handle-set-file-times (filename &optional time flag) |
| 544 | "Like `set-file-times' for Tramp files." | 543 | "Like `set-file-times' for Tramp files." |
| 545 | (with-parsed-tramp-file-name filename nil | 544 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 546 | (tramp-flush-file-properties v localname) | ||
| 547 | (let ((time | 545 | (let ((time |
| 548 | (if (or (null time) | 546 | (if (or (null time) |
| 549 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) | 547 | (tramp-compat-time-equal-p time tramp-time-doesnt-exist) |
| @@ -730,13 +728,13 @@ ID-FORMAT valid values are `string' and `integer'." | |||
| 730 | 728 | ||
| 731 | (defun tramp-sudoedit-handle-set-file-uid-gid (filename &optional uid gid) | 729 | (defun tramp-sudoedit-handle-set-file-uid-gid (filename &optional uid gid) |
| 732 | "Like `tramp-set-file-uid-gid' for Tramp files." | 730 | "Like `tramp-set-file-uid-gid' for Tramp files." |
| 733 | (with-parsed-tramp-file-name filename nil | 731 | (tramp-skeleton-set-file-modes-times-uid-gid filename |
| 734 | (tramp-sudoedit-send-command | 732 | (tramp-sudoedit-send-command |
| 735 | v "chown" | 733 | v "chown" |
| 736 | (format "%d:%d" | 734 | (format "%d:%d" |
| 737 | (or uid (tramp-get-remote-uid v 'integer)) | 735 | (or uid (tramp-get-remote-uid v 'integer)) |
| 738 | (or gid (tramp-get-remote-gid v 'integer))) | 736 | (or gid (tramp-get-remote-gid v 'integer))) |
| 739 | (tramp-unquote-file-local-name filename)))) | 737 | (tramp-unquote-file-local-name filename)))) |
| 740 | 738 | ||
| 741 | 739 | ||
| 742 | ;; Internal functions. | 740 | ;; Internal functions. |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 0afa6fc4312..aac63882ced 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -62,7 +62,6 @@ | |||
| 62 | (require 'cl-lib) | 62 | (require 'cl-lib) |
| 63 | (declare-function file-notify-rm-watch "filenotify") | 63 | (declare-function file-notify-rm-watch "filenotify") |
| 64 | (declare-function netrc-parse "netrc") | 64 | (declare-function netrc-parse "netrc") |
| 65 | (declare-function tramp-archive-file-name-handler "tramp-archive") | ||
| 66 | (defvar auto-save-file-name-transforms) | 65 | (defvar auto-save-file-name-transforms) |
| 67 | 66 | ||
| 68 | ;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU ELPA package. | 67 | ;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU ELPA package. |
| @@ -97,6 +96,7 @@ | |||
| 97 | If it is set to nil, all remote file names are used literally." | 96 | If it is set to nil, all remote file names are used literally." |
| 98 | :type 'boolean) | 97 | :type 'boolean) |
| 99 | 98 | ||
| 99 | ;;;###tramp-autoload | ||
| 100 | (defcustom tramp-verbose 3 | 100 | (defcustom tramp-verbose 3 |
| 101 | "Verbosity level for Tramp messages. | 101 | "Verbosity level for Tramp messages. |
| 102 | Any level x includes messages for all levels 1 .. x-1. The levels are | 102 | Any level x includes messages for all levels 1 .. x-1. The levels are |
| @@ -1441,8 +1441,9 @@ calling HANDLER.") | |||
| 1441 | ;; work otherwise when unloading / reloading Tramp. (Bug#50869) | 1441 | ;; work otherwise when unloading / reloading Tramp. (Bug#50869) |
| 1442 | ;;;###tramp-autoload(require 'cl-lib) | 1442 | ;;;###tramp-autoload(require 'cl-lib) |
| 1443 | ;;;###tramp-autoload | 1443 | ;;;###tramp-autoload |
| 1444 | (cl-defstruct (tramp-file-name (:type list) :named) | 1444 | (progn |
| 1445 | method user domain host port localname hop) | 1445 | (cl-defstruct (tramp-file-name (:type list) :named) |
| 1446 | method user domain host port localname hop)) | ||
| 1446 | 1447 | ||
| 1447 | (put #'tramp-file-name-method 'tramp-suppress-trace t) | 1448 | (put #'tramp-file-name-method 'tramp-suppress-trace t) |
| 1448 | (put #'tramp-file-name-user 'tramp-suppress-trace t) | 1449 | (put #'tramp-file-name-user 'tramp-suppress-trace t) |
| @@ -1485,13 +1486,22 @@ If nil, return `tramp-default-port'." | |||
| 1485 | 1486 | ||
| 1486 | (put #'tramp-file-name-port-or-default 'tramp-suppress-trace t) | 1487 | (put #'tramp-file-name-port-or-default 'tramp-suppress-trace t) |
| 1487 | 1488 | ||
| 1488 | (defun tramp-file-name-unify (vec) | 1489 | ;;;###tramp-autoload |
| 1490 | (defun tramp-file-name-unify (vec &optional file) | ||
| 1489 | "Unify VEC by removing localname and hop from `tramp-file-name' structure. | 1491 | "Unify VEC by removing localname and hop from `tramp-file-name' structure. |
| 1492 | If FILE is a string, set it as localname. | ||
| 1490 | Objects returned by this function compare `equal' if they refer to the | 1493 | Objects returned by this function compare `equal' if they refer to the |
| 1491 | same connection. Make a copy in order to avoid side effects." | 1494 | same connection. Make a copy in order to avoid side effects." |
| 1492 | (when (tramp-file-name-p vec) | 1495 | (when (tramp-file-name-p vec) |
| 1493 | (setq vec (copy-tramp-file-name vec)) | 1496 | (setq vec (copy-tramp-file-name vec)) |
| 1494 | (setf (tramp-file-name-localname vec) nil | 1497 | (setf (tramp-file-name-localname vec) |
| 1498 | (and (stringp file) | ||
| 1499 | ;; FIXME: This is a sanity check. When this error | ||
| 1500 | ;; doesn't happen for a while, it can be removed. | ||
| 1501 | (or (file-name-absolute-p file) | ||
| 1502 | (tramp-error | ||
| 1503 | vec 'file-error "File `%s' must be absolute" file)) | ||
| 1504 | (directory-file-name (tramp-compat-file-name-unquote file))) | ||
| 1495 | (tramp-file-name-hop vec) nil)) | 1505 | (tramp-file-name-hop vec) nil)) |
| 1496 | vec) | 1506 | vec) |
| 1497 | 1507 | ||
| @@ -1525,6 +1535,7 @@ entry does not exist, return nil." | |||
| 1525 | "Return unquoted localname component of VEC." | 1535 | "Return unquoted localname component of VEC." |
| 1526 | (tramp-compat-file-name-unquote (tramp-file-name-localname vec))) | 1536 | (tramp-compat-file-name-unquote (tramp-file-name-localname vec))) |
| 1527 | 1537 | ||
| 1538 | ;;;###tramp-autoload | ||
| 1528 | (defun tramp-tramp-file-p (name) | 1539 | (defun tramp-tramp-file-p (name) |
| 1529 | "Return t if NAME is a string with Tramp file name syntax." | 1540 | "Return t if NAME is a string with Tramp file name syntax." |
| 1530 | (and tramp-mode (stringp name) | 1541 | (and tramp-mode (stringp name) |
| @@ -1546,6 +1557,7 @@ entry does not exist, return nil." | |||
| 1546 | ;; However, it is more performant than `file-local-name', and might be | 1557 | ;; However, it is more performant than `file-local-name', and might be |
| 1547 | ;; useful where performance matters, like in operations over a bulk | 1558 | ;; useful where performance matters, like in operations over a bulk |
| 1548 | ;; list of file names. | 1559 | ;; list of file names. |
| 1560 | ;;;###tramp-autoload | ||
| 1549 | (defun tramp-file-local-name (name) | 1561 | (defun tramp-file-local-name (name) |
| 1550 | "Return the local name component of NAME. | 1562 | "Return the local name component of NAME. |
| 1551 | This function removes from NAME the specification of the remote | 1563 | This function removes from NAME the specification of the remote |
| @@ -1637,6 +1649,7 @@ This is HOST, if non-nil. Otherwise, do a lookup in | |||
| 1637 | 1649 | ||
| 1638 | (put #'tramp-find-host 'tramp-suppress-trace t) | 1650 | (put #'tramp-find-host 'tramp-suppress-trace t) |
| 1639 | 1651 | ||
| 1652 | ;;;###tramp-autoload | ||
| 1640 | (defun tramp-dissect-file-name (name &optional nodefault) | 1653 | (defun tramp-dissect-file-name (name &optional nodefault) |
| 1641 | "Return a `tramp-file-name' structure of NAME, a remote file name. | 1654 | "Return a `tramp-file-name' structure of NAME, a remote file name. |
| 1642 | The structure consists of method, user, domain, host, port, | 1655 | The structure consists of method, user, domain, host, port, |
| @@ -1747,6 +1760,7 @@ See `tramp-dissect-file-name' for details." | |||
| 1747 | 1760 | ||
| 1748 | (put #'tramp-buffer-name 'tramp-suppress-trace t) | 1761 | (put #'tramp-buffer-name 'tramp-suppress-trace t) |
| 1749 | 1762 | ||
| 1763 | ;;;###tramp-autoload | ||
| 1750 | (defun tramp-make-tramp-file-name (&rest args) | 1764 | (defun tramp-make-tramp-file-name (&rest args) |
| 1751 | "Construct a Tramp file name from ARGS. | 1765 | "Construct a Tramp file name from ARGS. |
| 1752 | 1766 | ||
| @@ -1856,6 +1870,7 @@ Unless DONT-CREATE, the buffer is created when it doesn't exist yet." | |||
| 1856 | (tramp-make-tramp-file-name vec 'noloc)) | 1870 | (tramp-make-tramp-file-name vec 'noloc)) |
| 1857 | (current-buffer))))) | 1871 | (current-buffer))))) |
| 1858 | 1872 | ||
| 1873 | ;;;###tramp-autoload | ||
| 1859 | (defun tramp-get-connection-buffer (vec &optional dont-create) | 1874 | (defun tramp-get-connection-buffer (vec &optional dont-create) |
| 1860 | "Get the connection buffer to be used for VEC. | 1875 | "Get the connection buffer to be used for VEC. |
| 1861 | Unless DONT-CREATE, the buffer is created when it doesn't exist yet. | 1876 | Unless DONT-CREATE, the buffer is created when it doesn't exist yet. |
| @@ -1912,8 +1927,7 @@ version, the function does nothing." | |||
| 1912 | "Return `default-directory' of BUFFER." | 1927 | "Return `default-directory' of BUFFER." |
| 1913 | (buffer-local-value 'default-directory buffer)) | 1928 | (buffer-local-value 'default-directory buffer)) |
| 1914 | 1929 | ||
| 1915 | (put #'tramp-get-default-directory 'tramp-suppress-trace t) | 1930 | ;;;###tramp-autoload |
| 1916 | |||
| 1917 | (defsubst tramp-get-buffer-string (&optional buffer) | 1931 | (defsubst tramp-get-buffer-string (&optional buffer) |
| 1918 | "Return contents of BUFFER. | 1932 | "Return contents of BUFFER. |
| 1919 | If BUFFER is not a buffer or a buffer name, return the contents | 1933 | If BUFFER is not a buffer or a buffer name, return the contents |
| @@ -1921,8 +1935,6 @@ of `current-buffer'." | |||
| 1921 | (with-current-buffer (or buffer (current-buffer)) | 1935 | (with-current-buffer (or buffer (current-buffer)) |
| 1922 | (substring-no-properties (buffer-string)))) | 1936 | (substring-no-properties (buffer-string)))) |
| 1923 | 1937 | ||
| 1924 | (put #'tramp-get-buffer-string 'tramp-suppress-trace t) | ||
| 1925 | |||
| 1926 | (defun tramp-debug-buffer-name (vec) | 1938 | (defun tramp-debug-buffer-name (vec) |
| 1927 | "A name for the debug buffer for VEC." | 1939 | "A name for the debug buffer for VEC." |
| 1928 | (let ((method (tramp-file-name-method vec)) | 1940 | (let ((method (tramp-file-name-method vec)) |
| @@ -2034,6 +2046,7 @@ They are completed by \"M-x TAB\" only in Tramp debug buffers." | |||
| 2034 | (defvar tramp-trace-functions nil | 2046 | (defvar tramp-trace-functions nil |
| 2035 | "A list of non-Tramp functions to be traced with `tramp-verbose' > 10.") | 2047 | "A list of non-Tramp functions to be traced with `tramp-verbose' > 10.") |
| 2036 | 2048 | ||
| 2049 | ;;;###tramp-autoload | ||
| 2037 | (defun tramp-debug-message (vec fmt-string &rest arguments) | 2050 | (defun tramp-debug-message (vec fmt-string &rest arguments) |
| 2038 | "Append message to debug buffer of VEC. | 2051 | "Append message to debug buffer of VEC. |
| 2039 | Message is formatted with FMT-STRING as control string and the remaining | 2052 | Message is formatted with FMT-STRING as control string and the remaining |
| @@ -2107,10 +2120,12 @@ ARGUMENTS to actually emit the message (if applicable)." | |||
| 2107 | 2120 | ||
| 2108 | (put #'tramp-debug-message 'tramp-suppress-trace t) | 2121 | (put #'tramp-debug-message 'tramp-suppress-trace t) |
| 2109 | 2122 | ||
| 2123 | ;;;###tramp-autoload | ||
| 2110 | (defvar tramp-inhibit-progress-reporter nil | 2124 | (defvar tramp-inhibit-progress-reporter nil |
| 2111 | "Show Tramp progress reporter in the minibuffer. | 2125 | "Show Tramp progress reporter in the minibuffer. |
| 2112 | This variable is used to disable concurrent progress reporter messages.") | 2126 | This variable is used to disable concurrent progress reporter messages.") |
| 2113 | 2127 | ||
| 2128 | ;;;###tramp-autoload | ||
| 2114 | (defsubst tramp-message (vec-or-proc level fmt-string &rest arguments) | 2129 | (defsubst tramp-message (vec-or-proc level fmt-string &rest arguments) |
| 2115 | "Emit a message depending on verbosity level. | 2130 | "Emit a message depending on verbosity level. |
| 2116 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a | 2131 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a |
| @@ -2163,8 +2178,6 @@ applicable)." | |||
| 2163 | (concat (format "(%d) # " level) fmt-string) | 2178 | (concat (format "(%d) # " level) fmt-string) |
| 2164 | arguments)))))) | 2179 | arguments)))))) |
| 2165 | 2180 | ||
| 2166 | (put #'tramp-message 'tramp-suppress-trace t) | ||
| 2167 | |||
| 2168 | (defsubst tramp-backtrace (&optional vec-or-proc force) | 2181 | (defsubst tramp-backtrace (&optional vec-or-proc force) |
| 2169 | "Dump a backtrace into the debug buffer. | 2182 | "Dump a backtrace into the debug buffer. |
| 2170 | If VEC-OR-PROC is nil, the buffer *debug tramp* is used. FORCE | 2183 | If VEC-OR-PROC is nil, the buffer *debug tramp* is used. FORCE |
| @@ -2177,8 +2190,6 @@ This function is meant for debugging purposes." | |||
| 2177 | vec-or-proc 10 "\n%s" (with-output-to-string (backtrace))) | 2190 | vec-or-proc 10 "\n%s" (with-output-to-string (backtrace))) |
| 2178 | (with-output-to-temp-buffer "*debug tramp*" (backtrace)))))) | 2191 | (with-output-to-temp-buffer "*debug tramp*" (backtrace)))))) |
| 2179 | 2192 | ||
| 2180 | (put #'tramp-backtrace 'tramp-suppress-trace t) | ||
| 2181 | |||
| 2182 | (defun tramp-error (vec-or-proc signal fmt-string &rest arguments) | 2193 | (defun tramp-error (vec-or-proc signal fmt-string &rest arguments) |
| 2183 | "Emit an error. | 2194 | "Emit an error. |
| 2184 | VEC-OR-PROC identifies the connection to use, SIGNAL is the | 2195 | VEC-OR-PROC identifies the connection to use, SIGNAL is the |
| @@ -2246,8 +2257,6 @@ an input event arrives. The other arguments are passed to `tramp-error'." | |||
| 2246 | (when (tramp-file-name-equal-p vec (car tramp-current-connection)) | 2257 | (when (tramp-file-name-equal-p vec (car tramp-current-connection)) |
| 2247 | (setcdr tramp-current-connection (current-time))))))) | 2258 | (setcdr tramp-current-connection (current-time))))))) |
| 2248 | 2259 | ||
| 2249 | (put #'tramp-error-with-buffer 'tramp-suppress-trace t) | ||
| 2250 | |||
| 2251 | ;; We must make it a defun, because it is used earlier already. | 2260 | ;; We must make it a defun, because it is used earlier already. |
| 2252 | (defun tramp-user-error (vec-or-proc fmt-string &rest arguments) | 2261 | (defun tramp-user-error (vec-or-proc fmt-string &rest arguments) |
| 2253 | "Signal a user error (or \"pilot error\")." | 2262 | "Signal a user error (or \"pilot error\")." |
| @@ -2284,8 +2293,6 @@ the resulting error message." | |||
| 2284 | (progn ,@body) | 2293 | (progn ,@body) |
| 2285 | (error (tramp-message ,vec-or-proc 3 ,format ,err) nil)))) | 2294 | (error (tramp-message ,vec-or-proc 3 ,format ,err) nil)))) |
| 2286 | 2295 | ||
| 2287 | (put #'tramp-with-demoted-errors 'tramp-suppress-trace t) | ||
| 2288 | |||
| 2289 | ;; This macro shall optimize the cases where an `file-exists-p' call | 2296 | ;; This macro shall optimize the cases where an `file-exists-p' call |
| 2290 | ;; is invoked first. Often, the file exists, so the remote command is | 2297 | ;; is invoked first. Often, the file exists, so the remote command is |
| 2291 | ;; superfluous. | 2298 | ;; superfluous. |
| @@ -2302,8 +2309,6 @@ does not exist, otherwise propagate the error." | |||
| 2302 | (tramp-error ,vec 'file-missing ,filename) | 2309 | (tramp-error ,vec 'file-missing ,filename) |
| 2303 | (signal (car ,err) (cdr ,err))))))) | 2310 | (signal (car ,err) (cdr ,err))))))) |
| 2304 | 2311 | ||
| 2305 | (put #'tramp-barf-if-file-missing 'tramp-suppress-trace t) | ||
| 2306 | |||
| 2307 | (defun tramp-test-message (fmt-string &rest arguments) | 2312 | (defun tramp-test-message (fmt-string &rest arguments) |
| 2308 | "Emit a Tramp message according `default-directory'." | 2313 | "Emit a Tramp message according `default-directory'." |
| 2309 | (cond | 2314 | (cond |
| @@ -2399,45 +2404,6 @@ without a visible progress reporter." | |||
| 2399 | (if tm (cancel-timer tm)) | 2404 | (if tm (cancel-timer tm)) |
| 2400 | (tramp-message ,vec ,level "%s...%s" ,message cookie))))) | 2405 | (tramp-message ,vec ,level "%s...%s" ,message cookie))))) |
| 2401 | 2406 | ||
| 2402 | (defmacro with-tramp-file-property (vec file property &rest body) | ||
| 2403 | "Check in Tramp cache for PROPERTY, otherwise execute BODY and set cache. | ||
| 2404 | FILE must be a local file name on a connection identified via VEC." | ||
| 2405 | (declare (indent 3) (debug t)) | ||
| 2406 | `(if (file-name-absolute-p ,file) | ||
| 2407 | (let ((value (tramp-get-file-property | ||
| 2408 | ,vec ,file ,property tramp-cache-undefined))) | ||
| 2409 | (when (eq value tramp-cache-undefined) | ||
| 2410 | ;; We cannot pass @body as parameter to | ||
| 2411 | ;; `tramp-set-file-property' because it mangles our debug | ||
| 2412 | ;; messages. | ||
| 2413 | (setq value (progn ,@body)) | ||
| 2414 | (tramp-set-file-property ,vec ,file ,property value)) | ||
| 2415 | value) | ||
| 2416 | ,@body)) | ||
| 2417 | |||
| 2418 | (defmacro with-tramp-connection-property (key property &rest body) | ||
| 2419 | "Check in Tramp for property PROPERTY, otherwise execute BODY and set." | ||
| 2420 | (declare (indent 2) (debug t)) | ||
| 2421 | `(let ((value (tramp-get-connection-property | ||
| 2422 | ,key ,property tramp-cache-undefined))) | ||
| 2423 | (when (eq value tramp-cache-undefined) | ||
| 2424 | ;; We cannot pass ,@body as parameter to | ||
| 2425 | ;; `tramp-set-connection-property' because it mangles our debug | ||
| 2426 | ;; messages. | ||
| 2427 | (setq value (progn ,@body)) | ||
| 2428 | (tramp-set-connection-property ,key ,property value)) | ||
| 2429 | value)) | ||
| 2430 | |||
| 2431 | (defmacro with-tramp-saved-connection-property (key property &rest body) | ||
| 2432 | "Save PROPERTY, run BODY, reset PROPERTY." | ||
| 2433 | (declare (indent 2) (debug t)) | ||
| 2434 | `(let ((value (tramp-get-connection-property | ||
| 2435 | ,key ,property tramp-cache-undefined))) | ||
| 2436 | (unwind-protect (progn ,@body) | ||
| 2437 | (if (eq value tramp-cache-undefined) | ||
| 2438 | (tramp-flush-connection-property ,key ,property) | ||
| 2439 | (tramp-set-connection-property ,key ,property value))))) | ||
| 2440 | |||
| 2441 | (defun tramp-drop-volume-letter (name) | 2407 | (defun tramp-drop-volume-letter (name) |
| 2442 | "Cut off unnecessary drive letter from file NAME. | 2408 | "Cut off unnecessary drive letter from file NAME. |
| 2443 | The functions `tramp-*-handle-expand-file-name' call `expand-file-name' | 2409 | The functions `tramp-*-handle-expand-file-name' call `expand-file-name' |
| @@ -3424,8 +3390,6 @@ BODY is the backend specific code." | |||
| 3424 | (tramp-dissect-file-name ,directory) 'file-missing ,directory)) | 3390 | (tramp-dissect-file-name ,directory) 'file-missing ,directory)) |
| 3425 | ,@body)) | 3391 | ,@body)) |
| 3426 | 3392 | ||
| 3427 | (put #'tramp-skeleton-copy-directory 'tramp-suppress-trace t) | ||
| 3428 | |||
| 3429 | (defmacro tramp-skeleton-delete-directory (directory recursive trash &rest body) | 3393 | (defmacro tramp-skeleton-delete-directory (directory recursive trash &rest body) |
| 3430 | "Skeleton for `tramp-*-handle-delete-directory'. | 3394 | "Skeleton for `tramp-*-handle-delete-directory'. |
| 3431 | BODY is the backend specific code." | 3395 | BODY is the backend specific code." |
| @@ -3441,8 +3405,6 @@ BODY is the backend specific code." | |||
| 3441 | ,@body) | 3405 | ,@body) |
| 3442 | (tramp-flush-directory-properties v localname))) | 3406 | (tramp-flush-directory-properties v localname))) |
| 3443 | 3407 | ||
| 3444 | (put #'tramp-skeleton-delete-directory 'tramp-suppress-trace t) | ||
| 3445 | |||
| 3446 | (defmacro tramp-skeleton-directory-files | 3408 | (defmacro tramp-skeleton-directory-files |
| 3447 | (directory &optional full match nosort count &rest body) | 3409 | (directory &optional full match nosort count &rest body) |
| 3448 | "Skeleton for `tramp-*-handle-directory-files'. | 3410 | "Skeleton for `tramp-*-handle-directory-files'. |
| @@ -3474,8 +3436,6 @@ BODY is the backend specific code." | |||
| 3474 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) | 3436 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) |
| 3475 | nil))) | 3437 | nil))) |
| 3476 | 3438 | ||
| 3477 | (put #'tramp-skeleton-directory-files 'tramp-suppress-trace t) | ||
| 3478 | |||
| 3479 | (defmacro tramp-skeleton-directory-files-and-attributes | 3439 | (defmacro tramp-skeleton-directory-files-and-attributes |
| 3480 | (directory &optional full match nosort id-format count &rest body) | 3440 | (directory &optional full match nosort id-format count &rest body) |
| 3481 | "Skeleton for `tramp-*-handle-directory-files-and-attributes'. | 3441 | "Skeleton for `tramp-*-handle-directory-files-and-attributes'. |
| @@ -3485,7 +3445,6 @@ BODY is the backend specific code." | |||
| 3485 | (with-parsed-tramp-file-name ,directory nil | 3445 | (with-parsed-tramp-file-name ,directory nil |
| 3486 | (tramp-barf-if-file-missing v ,directory | 3446 | (tramp-barf-if-file-missing v ,directory |
| 3487 | (when (file-directory-p ,directory) | 3447 | (when (file-directory-p ,directory) |
| 3488 | (setq ,directory (expand-file-name ,directory)) | ||
| 3489 | (let ((temp | 3448 | (let ((temp |
| 3490 | (copy-tree | 3449 | (copy-tree |
| 3491 | (mapcar | 3450 | (mapcar |
| @@ -3493,9 +3452,10 @@ BODY is the backend specific code." | |||
| 3493 | (cons | 3452 | (cons |
| 3494 | (car x) | 3453 | (car x) |
| 3495 | (tramp-convert-file-attributes | 3454 | (tramp-convert-file-attributes |
| 3496 | v (car x) ,id-format (cdr x)))) | 3455 | v (expand-file-name (car x) localname) |
| 3456 | ,id-format (cdr x)))) | ||
| 3497 | (with-tramp-file-property | 3457 | (with-tramp-file-property |
| 3498 | v localname ",directory-files-and-attributes" | 3458 | v localname "directory-files-and-attributes" |
| 3499 | ,@body)))) | 3459 | ,@body)))) |
| 3500 | result item) | 3460 | result item) |
| 3501 | 3461 | ||
| @@ -3524,10 +3484,8 @@ BODY is the backend specific code." | |||
| 3524 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) | 3484 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) |
| 3525 | nil))) | 3485 | nil))) |
| 3526 | 3486 | ||
| 3527 | (put #'tramp-skeleton-directory-files-and-attributes 'tramp-suppress-trace t) | ||
| 3528 | |||
| 3529 | (defmacro tramp-skeleton-file-local-copy (filename &rest body) | 3487 | (defmacro tramp-skeleton-file-local-copy (filename &rest body) |
| 3530 | "Skeleton for `tramp-*-handle-file-local-copy-files'. | 3488 | "Skeleton for `tramp-*-handle-file-local-copy'. |
| 3531 | BODY is the backend specific code." | 3489 | BODY is the backend specific code." |
| 3532 | (declare (indent 1) (debug t)) | 3490 | (declare (indent 1) (debug t)) |
| 3533 | `(with-parsed-tramp-file-name (file-truename ,filename) nil | 3491 | `(with-parsed-tramp-file-name (file-truename ,filename) nil |
| @@ -3541,7 +3499,22 @@ BODY is the backend specific code." | |||
| 3541 | ;; Trigger the `file-missing' error. | 3499 | ;; Trigger the `file-missing' error. |
| 3542 | (signal 'error nil))))) | 3500 | (signal 'error nil))))) |
| 3543 | 3501 | ||
| 3544 | (put #'tramp-skeleton-file-local-copy 'tramp-suppress-trace t) | 3502 | (defmacro tramp-skeleton-set-file-modes-times-uid-gid |
| 3503 | (filename &rest body) | ||
| 3504 | "Skeleton for `tramp-*-set-file-{modes,times,uid-gid}'. | ||
| 3505 | BODY is the backend specific code." | ||
| 3506 | (declare (indent 1) (debug t)) | ||
| 3507 | `(with-parsed-tramp-file-name ,filename nil | ||
| 3508 | (when (not (file-exists-p ,filename)) | ||
| 3509 | (tramp-error v 'file-missing ,filename)) | ||
| 3510 | (with-tramp-saved-file-properties | ||
| 3511 | v localname | ||
| 3512 | ;; We cannot add "file-attributes", "file-executable-p", | ||
| 3513 | ;; "file-ownership-preserved-p", "file-readable-p", | ||
| 3514 | ;; "file-writable-p". | ||
| 3515 | '("file-directory-p" "file-exists-p" "file-symlinkp" "file-truename") | ||
| 3516 | (tramp-flush-file-properties v localname)) | ||
| 3517 | ,@body)) | ||
| 3545 | 3518 | ||
| 3546 | (defmacro tramp-skeleton-write-region | 3519 | (defmacro tramp-skeleton-write-region |
| 3547 | (start end filename append visit lockname mustbenew &rest body) | 3520 | (start end filename append visit lockname mustbenew &rest body) |
| @@ -3602,6 +3575,9 @@ BODY is the backend specific code." | |||
| 3602 | ;; We must also flush the cache of the directory, because | 3575 | ;; We must also flush the cache of the directory, because |
| 3603 | ;; `file-attributes' reads the values from there. | 3576 | ;; `file-attributes' reads the values from there. |
| 3604 | (tramp-flush-file-properties v localname) | 3577 | (tramp-flush-file-properties v localname) |
| 3578 | ;; Set the "file-exists-p" file property, because it is | ||
| 3579 | ;; likely that it is needed shortly after `write-region'. | ||
| 3580 | (tramp-set-file-property v localname "file-exists-p" t) | ||
| 3605 | 3581 | ||
| 3606 | ;; We must protect `last-coding-system-used', now we have | 3582 | ;; We must protect `last-coding-system-used', now we have |
| 3607 | ;; set it to its correct value. | 3583 | ;; set it to its correct value. |
| @@ -3645,8 +3621,6 @@ BODY is the backend specific code." | |||
| 3645 | (tramp-message v 0 "Wrote %s" filename)) | 3621 | (tramp-message v 0 "Wrote %s" filename)) |
| 3646 | (run-hooks 'tramp-handle-write-region-hook)))))) | 3622 | (run-hooks 'tramp-handle-write-region-hook)))))) |
| 3647 | 3623 | ||
| 3648 | (put #'tramp-skeleton-write-region 'tramp-suppress-trace t) | ||
| 3649 | |||
| 3650 | ;;; Common file name handler functions for different backends: | 3624 | ;;; Common file name handler functions for different backends: |
| 3651 | 3625 | ||
| 3652 | (defvar tramp-handle-file-local-copy-hook nil | 3626 | (defvar tramp-handle-file-local-copy-hook nil |
| @@ -3843,7 +3817,9 @@ Let-bind it when necessary.") | |||
| 3843 | ;; We don't want to run it when `non-essential' is t, or there is | 3817 | ;; We don't want to run it when `non-essential' is t, or there is |
| 3844 | ;; no connection process yet. | 3818 | ;; no connection process yet. |
| 3845 | (when (tramp-connectable-p filename) | 3819 | (when (tramp-connectable-p filename) |
| 3846 | (not (null (file-attributes filename))))) | 3820 | (with-parsed-tramp-file-name filename nil |
| 3821 | (with-tramp-file-property v localname "file-exists-p" | ||
| 3822 | (not (null (file-attributes filename))))))) | ||
| 3847 | 3823 | ||
| 3848 | (defun tramp-handle-file-in-directory-p (filename directory) | 3824 | (defun tramp-handle-file-in-directory-p (filename directory) |
| 3849 | "Like `file-in-directory-p' for Tramp files." | 3825 | "Like `file-in-directory-p' for Tramp files." |
| @@ -5620,7 +5596,7 @@ the remote host use line-endings as defined in the variable | |||
| 5620 | (when vec | 5596 | (when vec |
| 5621 | (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) | 5597 | (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) |
| 5622 | (tramp-flush-connection-properties proc) | 5598 | (tramp-flush-connection-properties proc) |
| 5623 | (tramp-flush-directory-properties vec "")) | 5599 | (tramp-flush-directory-properties vec "/")) |
| 5624 | (when (buffer-live-p buf) | 5600 | (when (buffer-live-p buf) |
| 5625 | (with-current-buffer buf | 5601 | (with-current-buffer buf |
| 5626 | (when (and prompt (tramp-search-regexp (regexp-quote prompt))) | 5602 | (when (and prompt (tramp-search-regexp (regexp-quote prompt))) |
| @@ -6049,6 +6025,7 @@ Return the local name of the temporary file." | |||
| 6049 | (let (create-lockfiles) | 6025 | (let (create-lockfiles) |
| 6050 | (cl-letf (((symbol-function 'tramp-remote-acl-p) #'ignore) | 6026 | (cl-letf (((symbol-function 'tramp-remote-acl-p) #'ignore) |
| 6051 | ((symbol-function 'tramp-remote-selinux-p) #'ignore) | 6027 | ((symbol-function 'tramp-remote-selinux-p) #'ignore) |
| 6028 | ((symbol-function 'tramp-smb-remote-acl-p) #'ignore) | ||
| 6052 | ((symbol-function 'tramp-sudoedit-remote-acl-p) #'ignore) | 6029 | ((symbol-function 'tramp-sudoedit-remote-acl-p) #'ignore) |
| 6053 | ((symbol-function 'tramp-sudoedit-remote-selinux-p) #'ignore)) | 6030 | ((symbol-function 'tramp-sudoedit-remote-selinux-p) #'ignore)) |
| 6054 | (tramp-file-local-name | 6031 | (tramp-file-local-name |
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 5a8d9100e18..63ccd05a263 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el | |||
| @@ -2481,6 +2481,19 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2481 | (insert-file-contents tmp-name) | 2481 | (insert-file-contents tmp-name) |
| 2482 | (should (string-equal (buffer-string) "foo"))) | 2482 | (should (string-equal (buffer-string) "foo"))) |
| 2483 | 2483 | ||
| 2484 | ;; Write empty string. Used for creation of temprorary files. | ||
| 2485 | ;; Since Emacs 27.1. | ||
| 2486 | (when (fboundp 'make-empty-file) | ||
| 2487 | (with-no-warnings | ||
| 2488 | (should-error | ||
| 2489 | (make-empty-file tmp-name) | ||
| 2490 | :type 'file-already-exists) | ||
| 2491 | (delete-file tmp-name) | ||
| 2492 | (make-empty-file tmp-name) | ||
| 2493 | (with-temp-buffer | ||
| 2494 | (insert-file-contents tmp-name) | ||
| 2495 | (should (string-equal (buffer-string) ""))))) | ||
| 2496 | |||
| 2484 | ;; Write partly. | 2497 | ;; Write partly. |
| 2485 | (with-temp-buffer | 2498 | (with-temp-buffer |
| 2486 | (insert "123456789") | 2499 | (insert "123456789") |
| @@ -3790,7 +3803,11 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." | |||
| 3790 | (when (tramp--test-emacs28-p) | 3803 | (when (tramp--test-emacs28-p) |
| 3791 | (with-no-warnings | 3804 | (with-no-warnings |
| 3792 | (set-file-modes tmp-name1 #o222 'nofollow) | 3805 | (set-file-modes tmp-name1 #o222 'nofollow) |
| 3793 | (should (= (file-modes tmp-name1 'nofollow) #o222))))) | 3806 | (should (= (file-modes tmp-name1 'nofollow) #o222)))) |
| 3807 | ;; Setting the mode for not existing files shall fail. | ||
| 3808 | (should-error | ||
| 3809 | (set-file-modes tmp-name2 #o777) | ||
| 3810 | :type 'file-missing)) | ||
| 3794 | 3811 | ||
| 3795 | ;; Cleanup. | 3812 | ;; Cleanup. |
| 3796 | (ignore-errors (delete-file tmp-name1))) | 3813 | (ignore-errors (delete-file tmp-name1))) |
| @@ -4153,6 +4170,10 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." | |||
| 4153 | (tramp-compat-time-equal-p | 4170 | (tramp-compat-time-equal-p |
| 4154 | (file-attribute-modification-time (file-attributes tmp-name1)) | 4171 | (file-attribute-modification-time (file-attributes tmp-name1)) |
| 4155 | (seconds-to-time 1))) | 4172 | (seconds-to-time 1))) |
| 4173 | ;; Setting the time for not existing files shall fail. | ||
| 4174 | (should-error | ||
| 4175 | (set-file-times tmp-name2) | ||
| 4176 | :type 'file-missing) | ||
| 4156 | (write-region "bla" nil tmp-name2) | 4177 | (write-region "bla" nil tmp-name2) |
| 4157 | (should (file-exists-p tmp-name2)) | 4178 | (should (file-exists-p tmp-name2)) |
| 4158 | (should (file-newer-than-file-p tmp-name2 tmp-name1)) | 4179 | (should (file-newer-than-file-p tmp-name2 tmp-name1)) |