Function: tramp-file-name-handler
tramp-file-name-handler is an autoloaded and byte-compiled function
defined in tramp.el.gz.
Signature
(tramp-file-name-handler OPERATION &rest ARGS)
Documentation
Invoke Tramp file name handler for OPERATION and ARGS.
Fall back to normal file name handler if no Tramp file name handler exists.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp.el.gz
;; Main function.
;;;###autoload
(defun tramp-file-name-handler (operation &rest args)
"Invoke Tramp file name handler for OPERATION and ARGS.
Fall back to normal file name handler if no Tramp file name handler exists."
(let ((filename (apply #'tramp-file-name-for-operation operation args))
;; `file-remote-p' is called for everything, even for symbolic
;; links which look remote. We don't want to get an error.
(non-essential (or non-essential (eq operation 'file-remote-p))))
(if (tramp-tramp-file-p filename)
(save-match-data
(setq filename (tramp-replace-environment-variables filename))
(with-parsed-tramp-file-name filename nil
(let ((current-connection tramp-current-connection)
(foreign
(tramp-find-foreign-file-name-handler v operation))
(signal-hook-function #'tramp-signal-hook-function)
result)
;; Set `tramp-current-connection'.
(unless
(tramp-file-name-equal-p v (car tramp-current-connection))
(setq tramp-current-connection (list v)))
;; Call the backend function.
(unwind-protect
(if foreign
(let ((sf (symbol-function foreign)))
;; Some packages set the default directory to
;; a remote path, before respective Tramp
;; packages are already loaded. This results
;; in recursive loading. Therefore, we load
;; the Tramp packages locally.
(when (autoloadp sf)
;; FIXME: Not clear why we need these bindings here.
;; The explanation above is not convincing and
;; the bug#9114 for which it was added doesn't
;; clarify the core of the problem.
(let ((default-directory
tramp-compat-temporary-file-directory)
file-name-handler-alist)
(autoload-do-load sf foreign)))
(with-tramp-debug-message
v (format "Running `%S'" (cons operation args))
;; We flush connection properties
;; " process-name" and " process-buffer",
;; because the operations shall be applied
;; in the main connection process.
;; If `non-essential' is non-nil, Tramp shall
;; not open a new connection.
;; If Tramp detects that it shouldn't continue
;; to work, it throws the `suppress' event.
;; This could happen for example, when Tramp
;; tries to open the same connection twice in
;; a short time frame.
;; In both cases, we try the default handler then.
(with-tramp-saved-connection-properties
v '(" process-name" " process-buffer")
(tramp-flush-connection-property v " process-name")
(tramp-flush-connection-property v " process-buffer")
(setq result
(catch 'non-essential
(catch 'suppress
(apply foreign operation args))))))
(cond
((eq result 'non-essential)
(tramp-message
v 5 "Non-essential received in operation %s"
(cons operation args))
(tramp-backtrace v)
(tramp-run-real-handler operation args))
((eq result 'suppress)
(let ((inhibit-message t))
(tramp-message
v 1 "Suppress received in operation %s"
(cons operation args))
(tramp-cleanup-connection v t)
(tramp-run-real-handler operation args)))
(t result)))
;; Nothing to do for us. However, since we are in
;; `tramp-mode', we must suppress the volume
;; letter on MS Windows.
(setq result (tramp-run-real-handler operation args))
(if (stringp result)
(tramp-drop-volume-letter result)
result))
;; Reset `tramp-current-connection'.
(unless
(tramp-file-name-equal-p
(car current-connection) (car tramp-current-connection))
(setq tramp-current-connection current-connection))))))
;; When `tramp-mode' is not enabled, or the file name is quoted,
;; we don't do anything.
(tramp-run-real-handler operation args))))