Function: tramp-sh-handle-file-notify-add-watch

tramp-sh-handle-file-notify-add-watch is a byte-compiled function defined in tramp-sh.el.gz.

Signature

(tramp-sh-handle-file-notify-add-watch FILE-NAME FLAGS CALLBACK)

Documentation

Like file-notify-add-watch for Tramp files.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-sh.el.gz
(defun tramp-sh-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 ((default-directory (file-name-directory file-name))
          (process-environment
           (cons "GIO_USE_FILE_MONITOR=help" process-environment))
	  command events filter p sequence)
      (cond
       ;; "inotifywait".
       ((setq command (tramp-get-remote-inotifywait v))
	(setq filter #'tramp-sh-inotifywait-process-filter
	      events
	      (cond
	       ((and (memq 'change flags) (memq 'attribute-change flags))
		(concat "create,modify,move,moved_from,moved_to,move_self,"
			"delete,delete_self,attrib,ignored"))
	       ((memq 'change flags)
		(concat "create,modify,move,moved_from,moved_to,move_self,"
			"delete,delete_self,ignored"))
	       ((memq 'attribute-change flags) "attrib,ignored"))
	      ;; "-P" has been added to version 3.21, so we cannot assume it yet.
	      sequence `(,command "-mq" "-e" ,events ,localname)
	      ;; Make events a list of symbols.
	      events
	      (mapcar
	       (lambda (x) (intern-soft (tramp-compat-string-replace "_" "-" x)))
	       (split-string events "," 'omit))))
       ;; "gio monitor".
       ((setq command (tramp-get-remote-gio-monitor v))
	(setq filter #'tramp-sh-gio-monitor-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 "monitor" ,localname)))
       ;; None.
       (t (tramp-error
	   v 'file-notify-error
	   "No file notification program found on %s"
	   (file-remote-p file-name))))
      ;; Start process.
      (setq p (apply
	       #'start-file-process
	       (file-name-nondirectory command)
	       (generate-new-buffer
		(format " *%s*" (file-name-nondirectory command)))
	       sequence))
      ;; Return the process object as watch-descriptor.
      (if (not (processp p))
	  (tramp-error
	   v 'file-notify-error
	   "`%s' failed to start on remote host"
	   (string-join sequence " "))
	(tramp-message v 6 "Run `%s', %S" (string-join sequence " ") p)
	(process-put p 'tramp-vector v)
	;; This is needed for ssh or PuTTY based processes, and only if
	;; the respective options are set.  Perhaps, the setting could
	;; be more fine-grained.
	;; (process-put p 'tramp-shared-socket t)
	;; Needed for process filter.
	(process-put p 'tramp-events events)
	(process-put p 'tramp-watch-name localname)
	(set-process-query-on-exit-flag p nil)
	(set-process-filter p filter)
	(set-process-sentinel p #'tramp-file-notify-process-sentinel)
	;; There might be an error if the monitor is not supported.
	;; Give the filter a chance to read the output.
	(while (tramp-accept-process-output p))
	(unless (process-live-p p)
	  (tramp-error
	   p 'file-notify-error "Monitoring not supported for `%s'" file-name))
	p))))