summaryrefslogtreecommitdiff
path: root/lisp/net/tramp-sh.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/net/tramp-sh.el')
-rw-r--r--lisp/net/tramp-sh.el211
1 files changed, 68 insertions, 143 deletions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 7182cd6b1d9..c3e1745d2f2 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -2584,12 +2584,9 @@ The method used must be an out-of-band method."
(save-restriction
(narrow-to-region beg-marker end-marker)
;; Check for "--dired" output.
- (forward-line -2)
- (when (looking-at-p "//SUBDIRED//")
- (forward-line -1))
- (when (looking-at "//DIRED//\\s-+")
- (let ((beg (match-end 0))
- (end (point-at-eol)))
+ (when (re-search-backward "^//DIRED//\\s-+\\(.+\\)$" nil 'noerror)
+ (let ((beg (match-beginning 1))
+ (end (match-end 0)))
;; Now read the numeric positions of file names.
(goto-char beg)
(while (< (point) end)
@@ -2599,7 +2596,7 @@ The method used must be an out-of-band method."
;; End is followed by \n or by " -> ".
(put-text-property start end 'dired-filename t))))))
;; Remove trailing lines.
- (goto-char (point-at-bol))
+ (beginning-of-line)
(while (looking-at "//")
(forward-line 1)
(delete-region (match-beginning 0) (point))))
@@ -3654,6 +3651,8 @@ Fall back to normal file name handler if no Tramp handler exists."
(setq file-name (expand-file-name file-name))
(with-parsed-tramp-file-name file-name nil
(let ((default-directory (file-name-directory file-name))
+ (process-environment
+ (cons "GIO_USE_FILE_MONITOR=help" process-environment))
command events filter p sequence)
(cond
;; "inotifywait".
@@ -3686,18 +3685,6 @@ Fall back to normal file name handler if no Tramp handler exists."
'(created changed changes-done-hint moved deleted))
((memq 'attribute-change flags) '(attribute-changed)))
sequence `(,command "monitor" ,localname)))
- ;; "gvfs-monitor-dir".
- ((setq command (tramp-get-remote-gvfs-monitor-dir v))
- (setq filter #'tramp-sh-gvfs-monitor-dir-process-filter
- events
- (cond
- ((and (memq 'change flags) (memq 'attribute-change flags))
- '(created changed changes-done-hint moved deleted
- attribute-changed))
- ((memq 'change flags)
- '(created changed changes-done-hint moved deleted))
- ((memq 'attribute-change flags) '(attribute-changed)))
- sequence `(,command ,localname)))
;; None.
(t (tramp-error
v 'file-notify-error
@@ -3730,10 +3717,6 @@ Fall back to normal file name handler if no Tramp handler exists."
(unless (process-live-p p)
(tramp-error
p 'file-notify-error "Monitoring not supported for `%s'" file-name))
- ;; Set "gio-file-monitor" property if needed.
- (when (string-equal (file-name-nondirectory command) "gio")
- (tramp-set-connection-property
- p "gio-file-monitor" (tramp-get-remote-gio-file-monitor v)))
p))))
(defun tramp-sh-gio-monitor-process-filter (proc string)
@@ -3754,91 +3737,69 @@ Fall back to normal file name handler if no Tramp handler exists."
"changes done" "changes-done-hint" string)
string (tramp-compat-string-replace
"renamed to" "moved" string))
- ;; https://bugs.launchpad.net/bugs/1742946
- (when
- (string-match-p "Monitoring not supported\\|No locations given" string)
- (delete-process proc))
-
- ;; Delete empty lines.
- (setq string (tramp-compat-string-replace "\n\n" "\n" string))
-
- (while (string-match
- (eval-when-compile
- (concat "^[^:]+:"
- "[[:space:]]\\([^:]+\\):"
- "[[:space:]]" (regexp-opt tramp-gio-events t)
- "\\([[:space:]]\\([^:]+\\)\\)?$"))
- string)
-
- (let* ((file (match-string 1 string))
- (file1 (match-string 4 string))
- (object
- (list
- proc
- (list
- (intern-soft (match-string 2 string)))
- ;; File names are returned as absolute paths. We must
- ;; add the remote prefix.
- (concat remote-prefix file)
- (when file1 (concat remote-prefix file1)))))
- (setq string (replace-match "" nil nil string))
- ;; Usually, we would add an Emacs event now. Unfortunately,
- ;; `unread-command-events' does not accept several events at
- ;; once. Therefore, we apply the handler directly.
- (when (member (cl-caadr object) events)
- (tramp-compat-funcall
- (lookup-key special-event-map [file-notify])
- `(file-notify ,object file-notify-callback)))))
- ;; Save rest of the string.
- (when (zerop (length string)) (setq string nil))
- (when string (tramp-message proc 10 "Rest string:\n%s" string))
- (process-put proc 'rest-string string)))
-
-(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string)
- "Read output from \"gvfs-monitor-dir\" and add corresponding \
-`file-notify' events."
- (let ((events (process-get proc 'events))
- (remote-prefix
- (with-current-buffer (process-buffer proc)
- (file-remote-p default-directory)))
- (rest-string (process-get proc 'rest-string)))
- (when rest-string
- (tramp-message proc 10 "Previous string:\n%s" rest-string))
- (tramp-message proc 6 "%S\n%s" proc string)
- (setq string (concat rest-string string)
- ;; Attribute change is returned in unused wording.
- string (tramp-compat-string-replace
- "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
-
- (while (string-match
- (concat "^[\n\r]*"
- "Directory Monitor Event:[\n\r]+"
- "Child = \\([^\n\r]+\\)[\n\r]+"
- "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
- "Event = \\([^[:blank:]]+\\)[\n\r]+")
- string)
- (let* ((file (match-string 1 string))
- (file1 (match-string 3 string))
- (object
- (list
- proc
- (list
- (intern-soft
- (tramp-compat-string-replace
- "_" "-" (downcase (match-string 4 string)))))
- ;; File names are returned as absolute paths. We must
- ;; add the remote prefix.
- (concat remote-prefix file)
- (when file1 (concat remote-prefix file1)))))
- (setq string (replace-match "" nil nil string))
- ;; Usually, we would add an Emacs event now. Unfortunately,
- ;; `unread-command-events' does not accept several events at
- ;; once. Therefore, we apply the handler directly.
- (when (member (cl-caadr object) events)
- (tramp-compat-funcall
- (lookup-key special-event-map [file-notify])
- `(file-notify ,object file-notify-callback)))))
+ (catch 'doesnt-work
+ ;; https://bugs.launchpad.net/bugs/1742946
+ (when
+ (string-match-p "Monitoring not supported\\|No locations given" string)
+ (delete-process proc)
+ (throw 'doesnt-work nil))
+
+ ;; Determine monitor name.
+ (unless (tramp-connection-property-p proc "gio-file-monitor")
+ (cond
+ ;; We have seen this on cygwin gio and on emba. Let's make some assumptions.
+ ((string-match
+ "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string)
+ (cond
+ ((getenv "EMACS_EMBA_CI")
+ (tramp-set-connection-property
+ proc "gio-file-monitor" 'GInotifyFileMonitor))
+ ((eq system-type 'cygwin)
+ (tramp-set-connection-property
+ proc "gio-file-monitor" 'GPollFileMonitor))
+ (t (tramp-error proc 'file-error "Cannot determine gio monitor"))))
+ ;; TODO: What happens, if several monitor names are reported?
+ ((string-match "\
+Supported arguments for GIO_USE_FILE_MONITOR environment variable:
+\\s-*\\([[:alpha:]]+\\) - 20" string)
+ (tramp-set-connection-property
+ proc "gio-file-monitor"
+ (intern
+ (format "G%sFileMonitor" (capitalize (match-string 1 string))))))
+ (t (throw 'doesnt-work nil)))
+ (setq string (replace-match "" nil nil string)))
+
+ ;; Delete empty lines.
+ (setq string (tramp-compat-string-replace "\n\n" "\n" string))
+
+ (while (string-match
+ (eval-when-compile
+ (concat "^[^:]+:"
+ "[[:space:]]\\([^:]+\\):"
+ "[[:space:]]" (regexp-opt tramp-gio-events t)
+ "\\([[:space:]]\\([^:]+\\)\\)?$"))
+ string)
+
+ (let* ((file (match-string 1 string))
+ (file1 (match-string 4 string))
+ (object
+ (list
+ proc
+ (list
+ (intern-soft (match-string 2 string)))
+ ;; File names are returned as absolute paths. We
+ ;; must add the remote prefix.
+ (concat remote-prefix file)
+ (when file1 (concat remote-prefix file1)))))
+ (setq string (replace-match "" nil nil string))
+ ;; Usually, we would add an Emacs event now. Unfortunately,
+ ;; `unread-command-events' does not accept several events at
+ ;; once. Therefore, we apply the handler directly.
+ (when (member (cl-caadr object) events)
+ (tramp-compat-funcall
+ (lookup-key special-event-map [file-notify])
+ `(file-notify ,object file-notify-callback))))))
;; Save rest of the string.
(when (zerop (length string)) (setq string nil))
@@ -5647,42 +5608,6 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil."
(tramp-message vec 5 "Finding a suitable `gio-monitor' command")
(tramp-find-executable vec "gio" (tramp-get-remote-path vec) t t)))
-(defun tramp-get-remote-gio-file-monitor (vec)
- "Determine remote GFileMonitor."
- (with-tramp-connection-property vec "gio-file-monitor"
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 5 "Finding the used GFileMonitor")
- (when-let ((gio (tramp-get-remote-gio-monitor vec)))
- ;; Search for the used FileMonitor. There is no known way to
- ;; get this information directly from gio, so we check for
- ;; linked libraries of libgio.
- (when (tramp-send-command-and-check vec (concat "ldd " gio))
- (goto-char (point-min))
- (when (re-search-forward "\\S-+/libgio\\S-+")
- (when (tramp-send-command-and-check
- vec (concat "strings " (match-string 0)))
- (goto-char (point-min))
- (re-search-forward
- (format
- "^%s$"
- (regexp-opt
- '("GFamFileMonitor" "GFenFileMonitor"
- "GInotifyFileMonitor" "GKqueueFileMonitor")))
- nil 'noerror)
- (intern (match-string 0)))))))))
-
-(defun tramp-get-remote-gvfs-monitor-dir (vec)
- "Determine remote `gvfs-monitor-dir' command."
- (with-tramp-connection-property vec "gvfs-monitor-dir"
- (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command")
- ;; We distinguish "gvfs-monitor-dir.exe" from cygwin in order to
- ;; establish better timeouts in filenotify-tests.el. Any better
- ;; distinction approach would be welcome!
- (or (tramp-find-executable
- vec "gvfs-monitor-dir.exe" (tramp-get-remote-path vec) t t)
- (tramp-find-executable
- vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t))))
-
(defun tramp-get-remote-inotifywait (vec)
"Determine remote `inotifywait' command."
(with-tramp-connection-property vec "inotifywait"