summaryrefslogtreecommitdiff
path: root/lisp/net
diff options
context:
space:
mode:
authorMichael Albinus <michael.albinus@gmx.de>2013-01-29 17:03:40 +0100
committerMichael Albinus <michael.albinus@gmx.de>2013-01-29 17:03:40 +0100
commit2f52b5608c5dd7b5f1a4f339f1de8bfa43619ba1 (patch)
tree7b1a24900c8ba73c8f3c3b4c246a70c7ee3dabac /lisp/net
parentea55064c0b56c497ec1ecb9345212449f07ab580 (diff)
downloademacs-2f52b5608c5dd7b5f1a4f339f1de8bfa43619ba1.tar.gz
* autorevert.el (auto-revert-use-notify): Use
`custom-initialize-default' for initialization. (Bug#13583)
Diffstat (limited to 'lisp/net')
-rw-r--r--lisp/net/tramp-sh.el66
1 files changed, 65 insertions, 1 deletions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 63e966b91b2..65a514c8e36 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -988,7 +988,8 @@ This is used to map a mode number to a permission string.")
(set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
(file-acl . tramp-sh-handle-file-acl)
(set-file-acl . tramp-sh-handle-set-file-acl)
- (vc-registered . tramp-sh-handle-vc-registered))
+ (vc-registered . tramp-sh-handle-vc-registered)
+ (inotify-add-watch . tramp-sh-handle-inotify-add-watch))
"Alist of handler functions.
Operations not mentioned here will be handled by the normal Emacs functions.")
@@ -3487,6 +3488,64 @@ Fall back to normal file name handler if no Tramp handler exists."
;; Default file name handlers, we don't care.
(t (tramp-run-real-handler operation args)))))))
+(defun tramp-sh-handle-inotify-add-watch (file-name aspect callback)
+ "Like `inotify-add-watch' for Tramp files."
+ (setq file-name (expand-file-name file-name))
+ (unless (consp aspect) (setq aspect (cons aspect nil)))
+ (with-parsed-tramp-file-name file-name nil
+ (let* ((default-directory (file-name-directory file-name))
+ (command (tramp-get-remote-inotifywait v))
+ (aspect (mapconcat
+ (lambda (x)
+ (replace-regexp-in-string "-" "_" (symbol-name x)))
+ aspect ","))
+ (p (and command
+ (start-file-process
+ "inotifywait" nil command "-mq" "-e" aspect localname))))
+ (when (processp p)
+ (tramp-compat-set-process-query-on-exit-flag p nil)
+ (set-process-filter p 'tramp-sh-inotify-process-filter)
+ (tramp-set-connection-property p "inotify-callback" callback)
+ ;; Return the file-name vector as watch-descriptor.
+ (tramp-set-connection-property p "inotify-watch-descriptor" v)))))
+
+(defun tramp-sh-inotify-process-filter (proc string)
+ "Read output from \"inotifywait\" and add corresponding inotify events."
+ (tramp-message
+ (tramp-get-connection-property proc "vector" nil) 6
+ (format "%s\n%s" proc string))
+ (dolist (line (split-string string "[\n\r]+" 'omit-nulls))
+ ;; Check, whether there is a problem.
+ (unless
+ (string-match
+ "^[^[:blank:]]+[[:blank:]]+\\([^[:blank:]]+\\)+\\([[:blank:]]+\\([^[:blank:]]+\\)\\)?[[:blank:]]*$" line)
+ (tramp-error proc 'filewatch-error "%s" line))
+
+ (let* ((object
+ (list
+ (tramp-get-connection-property
+ proc "inotify-watch-descriptor" nil)
+ ;; Aspect symbols. We filter out MOVE and CLOSE, which
+ ;; are convenience macros. See INOTIFY(7).
+ (mapcar
+ (lambda (x)
+ (intern-soft (replace-regexp-in-string "_" "-" (downcase x))))
+ (delete "MOVE" (delete "CLOSE"
+ (split-string (match-string 1 line) "," 'omit-nulls))))
+ ;; We cannot gather any cookie value. So we return 0 as
+ ;; "don't know".
+ 0 (match-string 3 line)))
+ (callback
+ (tramp-get-connection-property proc "inotify-callback" nil))
+ (event `(file-inotify ,object ,callback)))
+
+ ;; 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.
+ ;(setq unread-command-events (cons event unread-command-events)))))
+ (let ((last-input-event event))
+ (funcall callback object)))))
+
;;; Internal Functions:
(defun tramp-maybe-send-script (vec script name)
@@ -5046,6 +5105,11 @@ This is used internally by `tramp-file-mode-from-int'."
(tramp-message vec 5 "Finding a suitable `trash' command")
(tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
+(defun tramp-get-remote-inotifywait (vec)
+ (with-tramp-connection-property vec "inotifywait"
+ (tramp-message vec 5 "Finding a suitable `inotifywait' command")
+ (tramp-find-executable vec "inotifywait" (tramp-get-remote-path vec) t t)))
+
(defun tramp-get-remote-id (vec)
(with-tramp-connection-property vec "id"
(tramp-message vec 5 "Finding POSIX `id' command")