From ddff5d3d879d23f0684b8abe7d923fce4f86ec2e Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 17 Dec 2020 18:52:23 +0100 Subject: [PATCH] Some minor Tramp changes * doc/lispref/os.texi (Timers): Speak about `remote-file-error'. * doc/misc/tramp.texi (Frequently Asked Questions): Speak about `remote-file-error'. (External packages): New subsection "Timers". * lisp/net/tramp-adb.el (tramp-adb-handle-make-process): * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Adapt error function. Handle coding. * lisp/net/tramp.el (tramp-handle-make-process): Adapt error function. --- doc/lispref/os.texi | 13 +++++++++++ doc/misc/tramp.texi | 52 +++++++++++++++++++++++++++++++++++++------ lisp/net/tramp-adb.el | 8 +++++-- lisp/net/tramp-sh.el | 13 +++++++++-- lisp/net/tramp.el | 2 +- 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index bc602205f5d..85f930d1897 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -2106,6 +2106,19 @@ run while waiting. If a timer function needs to perform an action after a certain time has elapsed, it can do this by scheduling a new timer. + If a timer function performs a remote file operation, it can be in +conflict with an already running remote file operation of the same +connection. Such conflicts are detected, and they result in a +@code{remote-file-error} error (@pxref{Standard Errors}). This should +be protected by wrapping the timer function body with + +@lisp +@group +(ignore-error 'remote-file-error + @dots{}) +@end group +@end lisp + If a timer function calls functions that can change the match data, it should save and restore the match data. @xref{Saving Match Data}. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 59b8bdbdf37..0557ca54695 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2508,7 +2508,7 @@ whatever shell is installed on the device with this setting: @lisp @group (add-to-list 'tramp-connection-properties - (list (regexp-quote "192.168.0.26") "remote-shell" "sh")) + (list (regexp-quote "192.168.0.26") "remote-shell" "sh")) @end group @end lisp @@ -2560,7 +2560,7 @@ the previous example, fix the connection properties as follows: @lisp @group (add-to-list 'tramp-connection-properties - (list (regexp-quote "android") "remote-shell" "sh")) + (list (regexp-quote "android") "remote-shell" "sh")) @end group @end lisp @@ -4341,9 +4341,9 @@ configure @file{~/.ssh/config} on the proxy host: @example @group Host * - ControlMaster auto - ControlPath tramp.%C - ControlPersist no + ControlMaster auto + ControlPath tramp.%C + ControlPersist no @end group @end example @@ -4877,6 +4877,25 @@ In case you have installed it from its Git repository, @ref{Recompilation}. @end ifset +@item +I get an error @samp{Remote file error: Forbidden reentrant call of Tramp} + +Timers, process filters and sentinels, and other event based functions +can run at any time, when a remote file operation is still running. +This can cause @value{tramp} to block. When such a situation is +detected, this error is triggered. It shall be fixed in the +respective function (an error report will help), but for the time +being you can suppress this error by the following code in your +@file{~/.emacs}: + +@lisp +@group +(setq debug-ignored-errors + (cons 'remote-file-error debug-ignored-errors)) +@end group +@end lisp + + @item How to disable other packages from calling @value{tramp}? @@ -4982,7 +5001,7 @@ handlers. @node External packages @section Integrating with external Lisp packages -@subsection File name completion. +@subsection File name completion @vindex non-essential Sometimes, it is not convenient to open a new connection to a remote @@ -5000,7 +5019,7 @@ bind it to non-@code{nil} value. @end lisp -@subsection File attributes cache. +@subsection File attributes cache Keeping a local cache of remote file attributes in sync with the remote host is a time-consuming operation. Flushing and re-querying @@ -5040,6 +5059,25 @@ root-directory, it is most likely sufficient to make the @code{default-directory} of the process buffer as the root directory. +@subsection Timers + +Timers run asynchronously at any time when Emacs is waiting for +sending a string to a process, or waiting for process output. They +can run any remote file operation, which would conflict with the +already running remote file operation, if the same connection is +affected. @value{tramp} detects this situation, and raises the +@code{remote-file-error} error. A timer function shall avoid this +situation. At least, it shall protect itself against this error, by +wrapping the timer function body with + +@lisp +@group +(ignore-error 'remote-file-error + @dots{}) +@end group +@end lisp + + @node Traces and Profiles @chapter How to Customize Traces @vindex tramp-verbose diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index f6e89339b68..9ea72668e7b 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -929,7 +929,7 @@ alternative implementation will be used." (unless (or (null sentinel) (functionp sentinel)) (signal 'wrong-type-argument (list #'functionp sentinel))) (unless (or (null stderr) (bufferp stderr) (stringp stderr)) - (signal 'wrong-type-argument (list #'stringp stderr))) + (signal 'wrong-type-argument (list #'bufferp stderr))) (when (and (stringp stderr) (tramp-tramp-file-p stderr) (not (tramp-equal-remote default-directory stderr))) (signal 'file-error (list "Wrong stderr" stderr))) @@ -981,7 +981,11 @@ alternative implementation will be used." ;; otherwise we might be interrupted by ;; `verify-visited-file-modtime'. (let ((buffer-undo-list t) - (inhibit-read-only t)) + (inhibit-read-only t) + (coding-system-for-write + (if (symbolp coding) coding (car coding))) + (coding-system-for-read + (if (symbolp coding) coding (cdr coding)))) (clear-visited-file-modtime) (narrow-to-region (point-max) (point-max)) ;; We call `tramp-adb-maybe-open-connection', diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index f4a93c840cf..e30fe61de43 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2871,7 +2871,7 @@ implementation will be used." (unless (or (null sentinel) (functionp sentinel)) (signal 'wrong-type-argument (list #'functionp sentinel))) (unless (or (null stderr) (bufferp stderr) (stringp stderr)) - (signal 'wrong-type-argument (list #'stringp stderr))) + (signal 'wrong-type-argument (list #'bufferp stderr))) (when (and (stringp stderr) (tramp-tramp-file-p stderr) (not (tramp-equal-remote default-directory stderr))) (signal 'file-error (list "Wrong stderr" stderr))) @@ -2985,7 +2985,11 @@ implementation will be used." ;; `verify-visited-file-modtime'. (let ((buffer-undo-list t) (inhibit-read-only t) - (mark (point-max))) + (mark (point-max)) + (coding-system-for-write + (if (symbolp coding) coding (car coding))) + (coding-system-for-read + (if (symbolp coding) coding (cdr coding)))) (clear-visited-file-modtime) (narrow-to-region (point-max) (point-max)) ;; We call `tramp-maybe-open-connection', in @@ -6139,4 +6143,9 @@ function cell is returned to be applied on a buffer." ;; ;; * Implement `:stderr' of `make-process' as pipe process. +;; * One interesting solution (with other applications as well) would +;; be to stipulate, as a directory or connection-local variable, an +;; additional rc file on the remote machine that is sourced every +;; time Tramp connects. + ;;; tramp-sh.el ends here diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 70bf1eee26b..a4865ec4f22 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3788,7 +3788,7 @@ It does not support `:stderr'." (unless (or (null sentinel) (functionp sentinel)) (signal 'wrong-type-argument (list #'functionp sentinel))) (unless (or (null stderr) (bufferp stderr)) - (signal 'wrong-type-argument (list #'stringp stderr))) + (signal 'wrong-type-argument (list #'bufferp stderr))) (let* ((buffer (if buffer -- 2.39.2