+2013-08-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Complete file name handlers.
+
+ * net/tramp.el (tramp-handle-set-visited-file-modtime)
+ (tramp-handle-verify-visited-file-modtime)
+ (tramp-handle-file-notify-rm-watch): New functions.
+ (tramp-call-process): Do not bind `default-directory'.
+
+ * net/tramp-adb.el (tramp-adb-file-name-handler-alist): Order
+ alphabetically.
+ [access-file, add-name-to-file, dired-call-process]:
+ [dired-compress-file, file-acl, file-notify-rm-watch]:
+ [file-ownership-preserved-p, file-selinux-context]:
+ [make-directory-internal, make-symbolic-link, set-file-acl]:
+ [set-file-selinux-context, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (tramp-adb-handle-write-region): Apply `set-visited-file-modtime'.
+
+ * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist)
+ [file-notify-add-watch, file-notify-rm-watch]:
+ [set-file-times, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (with-tramp-gvfs-error-message)
+ (tramp-gvfs-handle-set-visited-file-modtime)
+ (tramp-gvfs-fuse-file-name): Remove.
+ (tramp-gvfs-handle-file-notify-add-watch)
+ (tramp-gvfs-file-gvfs-monitor-file-process-filter): New defuns.
+ (tramp-gvfs-handle-write-region): Fix error in moving tmpfile.
+
+ * net/tramp-sh.el (tramp-sh-file-name-handler-alist): Order
+ alphabetically.
+ [file-notify-rm-watch ]: Use default Tramp handler.
+ [executable-find]: Remove private handler.
+ (tramp-do-copy-or-rename-file-out-of-band): Do not bind
+ `default-directory'.
+ (tramp-sh-handle-executable-find)
+ (tramp-sh-handle-file-notify-rm-watch): Remove functions.
+ (tramp-sh-file-gvfs-monitor-dir-process-filter)
+ (tramp-sh-file-inotifywait-process-filter, tramp-set-remote-path):
+ Do not use `format' in `tramp-message'.
+
+ * net/tramp-smb.el (tramp-smb-file-name-handler-alist)
+ [file-notify-rm-watch, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (tramp-smb-call-winexe): Do not bind `default-directory'.
+
2013-08-01 Xue Fuqiao <xfq.free@gmail.com>
* vc/vc-hooks.el (vc-menu-map): Fix menu entry for vc-ignore.
(cons 'tramp-adb-file-name-p 'tramp-adb-file-name-handler))
(defconst tramp-adb-file-name-handler-alist
- '((directory-file-name . tramp-handle-directory-file-name)
+ '((access-file . ignore)
+ (add-name-to-file . tramp-adb-handle-copy-file)
+ ;; `byte-compiler-base-file-name' performed by default handler.
+ ;; `copy-directory' performed by default handler.
+ (copy-file . tramp-adb-handle-copy-file)
+ (delete-directory . tramp-adb-handle-delete-directory)
+ (delete-file . tramp-adb-handle-delete-file)
+ ;; `diff-latest-backup-file' performed by default handler.
+ (directory-file-name . tramp-handle-directory-file-name)
+ (directory-files . tramp-handle-directory-files)
+ (directory-files-and-attributes
+ . tramp-adb-handle-directory-files-and-attributes)
+ (dired-call-process . ignore)
+ (dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
+ (expand-file-name . tramp-adb-handle-expand-file-name)
+ (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+ (file-acl . ignore)
+ (file-attributes . tramp-adb-handle-file-attributes)
+ (file-directory-p . tramp-adb-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
+ ;; FIXME: This is too sloppy.
+ (file-executable-p . tramp-handle-file-exists-p)
+ (file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
+ (file-local-copy . tramp-adb-handle-file-local-copy)
+ (file-modes . tramp-handle-file-modes)
+ (file-name-all-completions . tramp-adb-handle-file-name-all-completions)
(file-name-as-directory . tramp-handle-file-name-as-directory)
(file-name-completion . tramp-handle-file-name-completion)
- (file-name-all-completions . tramp-adb-handle-file-name-all-completions)
- (file-attributes . tramp-adb-handle-file-attributes)
(file-name-directory . tramp-handle-file-name-directory)
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
- (file-truename . tramp-adb-handle-file-truename)
+ ;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-name-as-directory . tramp-handle-file-name-as-directory)
+ (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-ownership-preserved-p . ignore)
+ (file-readable-p . tramp-handle-file-exists-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
- (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
- (file-directory-p . tramp-adb-handle-file-directory-p)
+ (file-selinux-context . ignore)
(file-symlink-p . tramp-handle-file-symlink-p)
- ;; FIXME: This is too sloppy.
- (file-executable-p . tramp-handle-file-exists-p)
- (file-exists-p . tramp-handle-file-exists-p)
- (file-readable-p . tramp-handle-file-exists-p)
+ (file-truename . tramp-adb-handle-file-truename)
(file-writable-p . tramp-adb-handle-file-writable-p)
- (file-local-copy . tramp-adb-handle-file-local-copy)
- (file-modes . tramp-handle-file-modes)
- (file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
- (expand-file-name . tramp-adb-handle-expand-file-name)
(find-backup-file-name . tramp-handle-find-backup-file-name)
- (directory-files . tramp-handle-directory-files)
- (directory-files-and-attributes
- . tramp-adb-handle-directory-files-and-attributes)
- (make-directory . tramp-adb-handle-make-directory)
- (delete-directory . tramp-adb-handle-delete-directory)
- (delete-file . tramp-adb-handle-delete-file)
- (load . tramp-handle-load)
+ ;; `find-file-noselect' performed by default handler.
+ ;; `get-file-buffer' performed by default handler.
(insert-directory . tramp-adb-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
- (substitute-in-file-name . tramp-handle-substitute-in-file-name)
- (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
- (vc-registered . ignore) ;no vc control files on Android devices
- (write-region . tramp-adb-handle-write-region)
+ (load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
+ (make-directory . tramp-adb-handle-make-directory)
+ (make-directory-internal . ignore)
+ (make-symbolic-link . ignore)
+ (process-file . tramp-adb-handle-process-file)
+ (rename-file . tramp-adb-handle-rename-file)
+ (set-file-acl . ignore)
(set-file-modes . tramp-adb-handle-set-file-modes)
+ (set-file-selinux-context . ignore)
(set-file-times . tramp-adb-handle-set-file-times)
- (copy-file . tramp-adb-handle-copy-file)
- (rename-file . tramp-adb-handle-rename-file)
- (process-file . tramp-adb-handle-process-file)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . tramp-adb-handle-shell-command)
- (start-file-process . tramp-adb-handle-start-file-process))
+ (start-file-process . tramp-adb-handle-start-file-process)
+ (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
+ (vc-registered . ignore)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-adb-handle-write-region))
"Alist of handler functions for Tramp ADB method.")
;; It must be a `defsubst' in order to push the whole code into
(tramp-error v 'file-error "Cannot write: `%s' filename"))
(delete-file tmpfile)))
+ (when (or (eq visit t) (stringp visit))
+ (set-visited-file-modtime))
+
(unless (equal curbuf (current-buffer))
(tramp-error
v 'file-error
\f
;; New handlers should be added here.
(defconst tramp-gvfs-file-name-handler-alist
- '(
- (access-file . ignore)
+ '((access-file . ignore)
(add-name-to-file . tramp-gvfs-handle-copy-file)
;; `byte-compiler-base-file-name' performed by default handler.
+ ;; `copy-directory' performed by default handler.
(copy-file . tramp-gvfs-handle-copy-file)
(delete-directory . tramp-gvfs-handle-delete-directory)
(delete-file . tramp-gvfs-handle-delete-file)
(dired-call-process . ignore)
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
- ;; `executable-find' is not official yet. performed by default handler.
(expand-file-name . tramp-gvfs-handle-expand-file-name)
(file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
(file-acl . ignore)
(file-attributes . tramp-gvfs-handle-file-attributes)
(file-directory-p . tramp-gvfs-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
(file-executable-p . tramp-gvfs-handle-file-executable-p)
(file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-gvfs-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
(file-name-all-completions . tramp-gvfs-handle-file-name-all-completions)
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
+ (file-notify-add-watch . tramp-gvfs-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-gvfs-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(insert-directory . tramp-gvfs-handle-insert-directory)
(insert-file-contents . tramp-gvfs-handle-insert-file-contents)
(load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
(make-directory . tramp-gvfs-handle-make-directory)
(make-directory-internal . ignore)
(make-symbolic-link . ignore)
(set-file-acl . ignore)
(set-file-modes . ignore)
(set-file-selinux-context . ignore)
- (set-visited-file-modtime . tramp-gvfs-handle-set-visited-file-modtime)
+ (set-file-times . ignore)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . ignore)
(start-file-process . ignore)
(substitute-in-file-name . tramp-handle-substitute-in-file-name)
(unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . ignore)
- ;; `verify-visited-file-modtime' performed by default handler.
- (write-region . tramp-gvfs-handle-write-region)
-)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-gvfs-handle-write-region))
"Alist of handler functions for Tramp GVFS method.
Operations not mentioned here will be handled by the default Emacs primitives.")
(tramp-compat-font-lock-add-keywords
'emacs-lisp-mode '("\\<with-tramp-dbus-call-method\\>"))
-(defmacro with-tramp-gvfs-error-message (filename handler &rest args)
- "Apply a Tramp GVFS `handler'.
-In case of an error, modify the error message by replacing
-`filename' with its GVFS mounted name."
- `(let ((fuse-file-name (regexp-quote (tramp-gvfs-fuse-file-name ,filename)))
- elt)
- (condition-case err
- (tramp-compat-funcall ,handler ,@args)
- (error
- (setq elt (cdr err))
- (while elt
- (when (and (stringp (car elt))
- (string-match fuse-file-name (car elt)))
- (setcar elt (replace-match ,filename t t (car elt))))
- (setq elt (cdr elt)))
- (signal (car err) (cdr err))))))
-
-(put 'with-tramp-gvfs-error-message 'lisp-indent-function 2)
-(put 'with-tramp-gvfs-error-message 'edebug-form-spec '(form symbolp body))
-(tramp-compat-font-lock-add-keywords
- 'emacs-lisp-mode '("\\<with-tramp-gvfs-error-message\\>"))
-
(defvar tramp-gvfs-dbus-event-vector nil
"Current Tramp file name to be used, as vector.
It is needed when D-Bus signals or errors arrive, because there
v (concat localname filename)
"file-name-all-completions" result))))))))
+(defun tramp-gvfs-handle-file-notify-add-watch (file-name flags callback)
+ "Like `file-notify-add-watch' for Tramp files."
+ (setq file-name (expand-file-name file-name))
+ (with-parsed-tramp-file-name file-name nil
+ (let ((p (start-process
+ "gvfs-monitor-file" (generate-new-buffer " *gvfs-monitor-file*")
+ "gvfs-monitor-file" (tramp-gvfs-url-file-name file-name))))
+ (if (not (processp p))
+ (tramp-error
+ v 'file-notify-error "gvfs-monitor-file failed to start")
+ (tramp-compat-set-process-query-on-exit-flag p nil)
+ (set-process-filter p 'tramp-gvfs-file-gvfs-monitor-file-process-filter)
+ (with-current-buffer (process-buffer p)
+ (setq default-directory (file-name-directory file-name)))
+ p))))
+
+(defun tramp-gvfs-file-gvfs-monitor-file-process-filter (proc string)
+ "Read output from \"gvfs-monitor-file\" and add corresponding file-notify events."
+ (let* ((rest-string (tramp-compat-process-get proc 'rest-string))
+ (dd (with-current-buffer (process-buffer proc) default-directory))
+ (ddu (regexp-quote (tramp-gvfs-url-file-name dd))))
+ (when rest-string
+ (tramp-message proc 10 "Previous string:\n%s" rest-string))
+ (tramp-message proc 6 "%S\n%s" proc string)
+ (setq string (concat rest-string string)
+ ;; Attribute change is returned in unused wording.
+ string (replace-regexp-in-string
+ "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+
+ (while (string-match
+ (concat "^[\n\r]*"
+ "File Monitor Event:[\n\r]+"
+ "File = \\([^\n\r]+\\)[\n\r]+"
+ "Event = \\([^[:blank:]]+\\)[\n\r]+")
+ string)
+ (let ((action (intern-soft
+ (replace-regexp-in-string
+ "_" "-" (downcase (match-string 2 string)))))
+ (file (match-string 1 string)))
+ (setq string (replace-match "" nil nil string))
+ ;; File names are returned as URL paths. We must convert them.
+ (when (string-match ddu file)
+ (setq file (replace-match dd nil nil file)))
+ (while (string-match "%\\([0-9A-F]\\{2\\}\\)" file)
+ (setq file
+ (replace-match
+ (char-to-string (string-to-number (match-string 1 file) 16))
+ nil nil file)))
+ ;; Usually, we would add an Emacs event now. Unfortunately,
+ ;; `unread-command-events' does not accept several events at
+ ;; once. Therefore, we apply the callback directly.
+ (tramp-compat-funcall 'file-notify-callback (list proc action file))))
+
+ ;; Save rest of the string.
+ (when (zerop (length string)) (setq string nil))
+ (when string (tramp-message proc 10 "Rest string:\n%s" string))
+ (tramp-compat-process-put proc 'rest-string string)))
+
(defun tramp-gvfs-handle-file-readable-p (filename)
"Like `file-readable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname))))))
-(defun tramp-gvfs-handle-set-visited-file-modtime (&optional time-list)
- "Like `set-visited-file-modtime' for Tramp files."
- (unless (buffer-file-name)
- (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
- (buffer-name)))
- (unless time-list
- (let ((f (buffer-file-name)))
- (with-parsed-tramp-file-name f nil
- (let ((remote-file-name-inhibit-cache t)
- (attr (file-attributes f)))
- ;; '(-1 65535) means file doesn't exists yet.
- (setq time-list (or (nth 5 attr) '(-1 65535)))))))
- ;; We use '(0 0) as a don't-know value.
- (unless (not (equal time-list '(0 0)))
- (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
-
(defun tramp-gvfs-handle-write-region
(start end filename &optional append visit lockname confirm)
"Like `write-region' for Tramp files."
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(write-region start end tmpfile)
(condition-case nil
- (rename-file tmpfile filename)
+ (rename-file tmpfile filename 'ok-if-already-exists)
(error
(delete-file tmpfile)
(tramp-error
(dbus-unescape-from-identifier
(replace-regexp-in-string "^.*/\\([^/]+\\)$" "\\1" object-path)))
-(defun tramp-gvfs-fuse-file-name (filename)
- "Return FUSE file name, which is directly accessible."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (tramp-gvfs-maybe-open-connection v)
- (let ((prefix (tramp-get-file-property v "/" "prefix" ""))
- (fuse-mountpoint
- (tramp-get-file-property v "/" "fuse-mountpoint" nil)))
- (unless fuse-mountpoint
- (tramp-error
- v 'file-error "There is no FUSE mount point for `%s'" filename))
- ;; We must hide the prefix, if any.
- (when (string-match (concat "^" (regexp-quote prefix)) localname)
- (setq localname (replace-match "" t t localname)))
- (tramp-message
- v 10 "remote file `%s' is local file `%s'"
- filename (concat fuse-mountpoint localname))
- (concat fuse-mountpoint localname))))
-
(defun tramp-bluez-address (device)
"Return bluetooth device address from a given bluetooth DEVICE name."
(when (stringp device)
here-document, otherwise the command could exceed maximum length
of command line.")
-;; New handlers should be added here. The following operations can be
-;; handled using the normal primitives: file-name-sans-versions,
-;; get-file-buffer.
+;; New handlers should be added here.
(defconst tramp-sh-file-name-handler-alist
- '((load . tramp-handle-load)
- (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
- (file-name-as-directory . tramp-handle-file-name-as-directory)
- (file-name-directory . tramp-handle-file-name-directory)
- (file-name-nondirectory . tramp-handle-file-name-nondirectory)
- (file-truename . tramp-sh-handle-file-truename)
- (file-exists-p . tramp-sh-handle-file-exists-p)
- (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
- (file-directory-p . tramp-sh-handle-file-directory-p)
- (file-executable-p . tramp-sh-handle-file-executable-p)
- (file-readable-p . tramp-sh-handle-file-readable-p)
- (file-regular-p . tramp-handle-file-regular-p)
- (file-symlink-p . tramp-handle-file-symlink-p)
- (file-writable-p . tramp-sh-handle-file-writable-p)
- (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
- (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
- (file-attributes . tramp-sh-handle-file-attributes)
- (file-modes . tramp-handle-file-modes)
- (directory-files . tramp-handle-directory-files)
- (directory-files-and-attributes
- . tramp-sh-handle-directory-files-and-attributes)
- (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
- (file-name-completion . tramp-handle-file-name-completion)
+ '(;; `access-file' performed by default handler.
(add-name-to-file . tramp-sh-handle-add-name-to-file)
- (copy-file . tramp-sh-handle-copy-file)
+ ;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-sh-handle-copy-directory)
- (rename-file . tramp-sh-handle-rename-file)
- (set-file-modes . tramp-sh-handle-set-file-modes)
- (set-file-times . tramp-sh-handle-set-file-times)
- (make-directory . tramp-sh-handle-make-directory)
+ (copy-file . tramp-sh-handle-copy-file)
(delete-directory . tramp-sh-handle-delete-directory)
(delete-file . tramp-sh-handle-delete-file)
+ ;; `diff-latest-backup-file' performed by default handler.
(directory-file-name . tramp-handle-directory-file-name)
- ;; `executable-find' is not official yet.
- (executable-find . tramp-sh-handle-executable-find)
- (start-file-process . tramp-sh-handle-start-file-process)
- (process-file . tramp-sh-handle-process-file)
- (shell-command . tramp-handle-shell-command)
- (insert-directory . tramp-sh-handle-insert-directory)
+ (directory-files . tramp-handle-directory-files)
+ (directory-files-and-attributes
+ . tramp-sh-handle-directory-files-and-attributes)
+ ;; `dired-call-process' performed by default handler.
+ (dired-compress-file . tramp-sh-handle-dired-compress-file)
+ (dired-recursive-delete-directory
+ . tramp-sh-handle-dired-recursive-delete-directory)
+ (dired-uncache . tramp-handle-dired-uncache)
(expand-file-name . tramp-sh-handle-expand-file-name)
- (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+ (file-acl . tramp-sh-handle-file-acl)
+ (file-attributes . tramp-sh-handle-file-attributes)
+ (file-directory-p . tramp-sh-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
+ (file-executable-p . tramp-sh-handle-file-executable-p)
+ (file-exists-p . tramp-sh-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-sh-handle-file-local-copy)
+ (file-modes . tramp-handle-file-modes)
+ (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
+ (file-name-as-directory . tramp-handle-file-name-as-directory)
+ (file-name-completion . tramp-handle-file-name-completion)
+ (file-name-directory . tramp-handle-file-name-directory)
+ (file-name-nondirectory . tramp-handle-file-name-nondirectory)
+ ;; `file-name-sans-versions' performed by default handler.
+ (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
+ (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
+ (file-readable-p . tramp-sh-handle-file-readable-p)
+ (file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
+ (file-selinux-context . tramp-sh-handle-file-selinux-context)
+ (file-symlink-p . tramp-handle-file-symlink-p)
+ (file-truename . tramp-sh-handle-file-truename)
+ (file-writable-p . tramp-sh-handle-file-writable-p)
+ (find-backup-file-name . tramp-handle-find-backup-file-name)
+ ;; `find-file-noselect' performed by default handler.
+ ;; `get-file-buffer' performed by default handler.
+ (insert-directory . tramp-sh-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
(insert-file-contents-literally
. tramp-sh-handle-insert-file-contents-literally)
- (write-region . tramp-sh-handle-write-region)
- (find-backup-file-name . tramp-handle-find-backup-file-name)
+ (load . tramp-handle-load)
(make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name)
- (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
- (dired-compress-file . tramp-sh-handle-dired-compress-file)
- (dired-recursive-delete-directory
- . tramp-sh-handle-dired-recursive-delete-directory)
- (dired-uncache . tramp-handle-dired-uncache)
- (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
- (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
- (file-selinux-context . tramp-sh-handle-file-selinux-context)
- (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
- (file-acl . tramp-sh-handle-file-acl)
+ (make-directory . tramp-sh-handle-make-directory)
+ (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
+ (process-file . tramp-sh-handle-process-file)
+ (rename-file . tramp-sh-handle-rename-file)
(set-file-acl . tramp-sh-handle-set-file-acl)
+ (set-file-modes . tramp-sh-handle-set-file-modes)
+ (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
+ (set-file-times . tramp-sh-handle-set-file-times)
+ (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
+ (shell-command . tramp-handle-shell-command)
+ (start-file-process . tramp-sh-handle-start-file-process)
+ (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . tramp-sh-handle-vc-registered)
- (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
- (file-notify-rm-watch . tramp-sh-handle-file-notify-rm-watch))
+ (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
+ (write-region . tramp-sh-handle-write-region))
"Alist of handler functions.
Operations not mentioned here will be handled by the normal Emacs functions.")
(tramp-get-method-parameter method 'tramp-copy-env))))
;; Check for program.
- (unless (let ((default-directory
- (tramp-compat-temporary-file-directory)))
- (executable-find copy-program))
+ (unless (executable-find copy-program)
(tramp-error
v 'file-error "Cannot find copy program: %s" copy-program))
;;; Remote commands:
-(defun tramp-sh-handle-executable-find (command)
- "Like `executable-find' for Tramp files."
- (with-parsed-tramp-file-name default-directory nil
- (tramp-find-executable v command (tramp-get-remote-path v) t)))
-
(defun tramp-process-sentinel (proc event)
"Flush file caches."
(unless (memq (process-status proc) '(run open))
(file-remote-p default-directory)))
(rest-string (tramp-compat-process-get proc 'rest-string)))
(when rest-string
- (tramp-message proc 10 (format "Previous string:\n%s" rest-string)))
- (tramp-message proc 6 (format "%S\n%s" proc string))
+ (tramp-message proc 10 "Previous string:\n%s" rest-string))
+ (tramp-message proc 6 "%S\n%s" proc string)
(setq string (concat rest-string string)
;; Attribute change is returned in unused wording.
string (replace-regexp-in-string
;; Save rest of the string.
(when (zerop (length string)) (setq string nil))
- (when string (tramp-message proc 10 (format "Rest string:\n%s" string)))
+ (when string (tramp-message proc 10 "Rest string:\n%s" string))
(tramp-compat-process-put proc 'rest-string string)))
(defun tramp-sh-file-inotifywait-process-filter (proc string)
"Read output from \"inotifywait\" and add corresponding file-notify events."
- (tramp-message proc 6 (format "%S\n%s" proc string))
+ (tramp-message proc 6 "%S\n%s" proc string)
(dolist (line (split-string string "[\n\r]+" 'omit-nulls))
;; Check, whether there is a problem.
(unless
;; once. Therefore, we apply the callback directly.
(tramp-compat-funcall 'file-notify-callback object))))
-(defvar file-notify-descriptors)
-(defun tramp-sh-handle-file-notify-rm-watch (proc)
- "Like `file-notify-rm-watch' for Tramp files."
- ;; The descriptor must be a process object.
- (unless (and (processp proc) (gethash proc file-notify-descriptors))
- (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
- (tramp-message proc 6 (format "Kill %S" proc))
- (kill-process proc))
-
;;; Internal Functions:
(defun tramp-maybe-send-script (vec script name)
I.e., for each directory in `tramp-remote-path', it is tested
whether it exists and if so, it is added to the environment
variable PATH."
- (tramp-message vec 5 (format "Setting $PATH environment variable"))
+ (tramp-message vec 5 "Setting $PATH environment variable")
(tramp-send-command
vec (format "PATH=%s; export PATH"
(mapconcat 'identity (tramp-get-remote-path vec) ":"))))
;; New handlers should be added here.
(defconst tramp-smb-file-name-handler-alist
- '(
- ;; `access-file' performed by default handler.
+ '(;; `access-file' performed by default handler.
(add-name-to-file . tramp-smb-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-smb-handle-copy-directory)
(file-acl . tramp-smb-handle-file-acl)
(file-attributes . tramp-smb-handle-file-attributes)
(file-directory-p . tramp-smb-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
(file-executable-p . tramp-handle-file-exists-p)
(file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-smb-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
(file-name-all-completions . tramp-smb-handle-file-name-all-completions)
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
(file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-handle-file-exists-p)
(file-regular-p . tramp-handle-file-regular-p)
(insert-directory . tramp-smb-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
(load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
(make-directory . tramp-smb-handle-make-directory)
(make-directory-internal . tramp-smb-handle-make-directory-internal)
(make-symbolic-link . tramp-smb-handle-make-symbolic-link)
(set-file-modes . tramp-smb-handle-set-file-modes)
(set-file-selinux-context . ignore)
(set-file-times . ignore)
- (set-visited-file-modtime . ignore)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . tramp-handle-shell-command)
(start-file-process . tramp-smb-handle-start-file-process)
(substitute-in-file-name . tramp-smb-handle-substitute-in-file-name)
(unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . ignore)
- (verify-visited-file-modtime . ignore)
- (write-region . tramp-smb-handle-write-region)
-)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-smb-handle-write-region))
"Alist of handler functions for Tramp SMB method.
Operations not mentioned here will be handled by the default Emacs primitives.")
(tramp-get-buffer vec)
;; Check for program.
- (unless (let ((default-directory
- (tramp-compat-temporary-file-directory)))
- (executable-find tramp-smb-winexe-program))
+ (unless (executable-find tramp-smb-winexe-program)
(tramp-error
vec 'file-error "Cannot find program: %s" tramp-smb-winexe-program))
'dired-compress-file 'dired-uncache
'file-accessible-directory-p 'file-attributes
'file-directory-p 'file-executable-p 'file-exists-p
- 'file-local-copy 'file-remote-p 'file-modes
+ 'file-local-copy 'file-modes
'file-name-as-directory 'file-name-directory
'file-name-nondirectory 'file-name-sans-versions
'file-ownership-preserved-p 'file-readable-p
- 'file-regular-p 'file-symlink-p 'file-truename
+ 'file-regular-p 'file-remote-p 'file-symlink-p 'file-truename
'file-writable-p 'find-backup-file-name 'find-file-noselect
'get-file-buffer 'insert-directory 'insert-file-contents
'load 'make-directory 'make-directory-internal
;; Emacs 23+ only.
'copy-directory
;; Emacs 24+ only.
- 'file-in-directory-p 'file-equal-p
+ 'file-equal-p 'file-in-directory-p
;; XEmacs only.
'dired-make-relative-symlink
'vm-imap-move-mail 'vm-pop-move-mail 'vm-spool-move-mail))
;; for backward compatibility.
(expand-file-name "~/"))
+(defun tramp-handle-set-visited-file-modtime (&optional time-list)
+ "Like `set-visited-file-modtime' for Tramp files."
+ (unless (buffer-file-name)
+ (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
+ (buffer-name)))
+ (unless time-list
+ (let ((remote-file-name-inhibit-cache t))
+ ;; '(-1 65535) means file doesn't exists yet.
+ (setq time-list
+ (or (nth 5 (file-attributes (buffer-file-name))) '(-1 65535)))))
+ ;; We use '(0 0) as a don't-know value.
+ (unless (equal time-list '(0 0))
+ (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
+
+(defun tramp-handle-verify-visited-file-modtime (&optional buf)
+ "Like `verify-visited-file-modtime' for Tramp files.
+At the time `verify-visited-file-modtime' calls this function, we
+already know that the buffer is visiting a file and that
+`visited-file-modtime' does not return 0. Do not call this
+function directly, unless those two cases are already taken care
+of."
+ (with-current-buffer (or buf (current-buffer))
+ (let ((f (buffer-file-name)))
+ ;; There is no file visiting the buffer, or the buffer has no
+ ;; recorded last modification time, or there is no established
+ ;; connection.
+ (if (or (not f)
+ (eq (visited-file-modtime) 0)
+ (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
+ t
+ (with-parsed-tramp-file-name f nil
+ (let* ((remote-file-name-inhibit-cache t)
+ (attr (file-attributes f))
+ (modtime (nth 5 attr))
+ (mt (visited-file-modtime)))
+
+ (cond
+ ;; File exists, and has a known modtime.
+ ((and attr (not (equal modtime '(0 0))))
+ (< (abs (tramp-time-diff
+ modtime
+ ;; For compatibility, deal with both the old
+ ;; (HIGH . LOW) and the new (HIGH LOW) return
+ ;; values of `visited-file-modtime'.
+ (if (atom (cdr mt))
+ (list (car mt) (cdr mt))
+ mt)))
+ 2))
+ ;; Modtime has the don't know value.
+ (attr t)
+ ;; If file does not exist, say it is not modified if and
+ ;; only if that agrees with the buffer's record.
+ (t (equal mt '(-1 65535))))))))))
+
(defun tramp-handle-file-notify-add-watch (filename flags callback)
"Like `file-notify-add-watch' for Tramp files."
- ;; This is the default handler. Some packages might have its own one.
+ ;; This is the default handler. tramp-gvfs.el and tramp-sh.el have
+ ;; its own one.
(setq filename (expand-file-name filename))
(with-parsed-tramp-file-name filename nil
(tramp-error
v 'file-notify-error "File notification not supported for `%s'" filename)))
+(defvar file-notify-descriptors)
+(defun tramp-handle-file-notify-rm-watch (proc)
+ "Like `file-notify-rm-watch' for Tramp files."
+ ;; The descriptor must be a process object.
+ (unless (and (processp proc) (gethash proc file-notify-descriptors))
+ (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
+ (tramp-message proc 6 "Kill %S" proc)
+ (kill-process proc))
+
;;; Functions for establishing connection:
;; The following functions are actions to be taken when seeing certain
defadvised `call-process' to behave like `process-file'. The
Lisp error raised when PROGRAM is nil is trapped also, returning 1.
Furthermore, traces are written with verbosity of 6."
- (let ((default-directory
- (if (file-remote-p default-directory)
- (tramp-compat-temporary-file-directory)
- default-directory)))
- (tramp-message
- (vector tramp-current-method tramp-current-user tramp-current-host nil nil)
- 6 "%s %s %s" program infile args)
- (if (executable-find program)
- (apply 'call-process program infile destination display args)
- 1)))
+ (tramp-message
+ (vector tramp-current-method tramp-current-user tramp-current-host nil nil)
+ 6 "%s %s %s" program infile args)
+ (if (executable-find program)
+ (apply 'call-process program infile destination display args)
+ 1))
;;;###tramp-autoload
(defun tramp-read-passwd (proc &optional prompt)