aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2019-04-29 16:42:04 +0200
committerMattias EngdegÄrd2019-05-02 15:45:04 +0200
commite13b8c0e405f1b5b78a1eeb3c33422b2fc93f002 (patch)
treec8e11c026d75aa5d53caa4a195c30172135abb1a
parent0efaae78f2b66de7ebeff7d1c16771ddafdf2d06 (diff)
downloademacs-e13b8c0e405f1b5b78a1eeb3c33422b2fc93f002.tar.gz
emacs-e13b8c0e405f1b5b78a1eeb3c33422b2fc93f002.zip
Small code clean-up of file-notify-add-watch
* lisp/filenotify.el (file-notify-add-watch): Clearly separate backend-specific code from the rest, and simplify. (file-notify--add-watch-inotify, file-notify--add-watch-kqueue) (file-notify--add-watch-w32notify, file-notify--add-watch-gfilenotify): New functions.
-rw-r--r--lisp/filenotify.el130
1 files changed, 67 insertions, 63 deletions
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index 62dd1cd9117..4d22061138f 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -262,9 +262,49 @@ EVENT is the cadr of the event in `file-notify-handle-event'
262 file (file-notify--event-watched-file event)))) 262 file (file-notify--event-watched-file event))))
263 (file-notify-rm-watch desc))))))) 263 (file-notify-rm-watch desc)))))))
264 264
265;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor 265(declare-function inotify-add-watch "inotify.c" (file flags callback))
266;; for every `file-notify-add-watch', while `inotify' returns a unique 266(declare-function kqueue-add-watch "kqueue.c" (file flags callback))
267;; descriptor per inode only. 267(declare-function w32notify-add-watch "w32notify.c" (file flags callback))
268(declare-function gfile-add-watch "gfilenotify.c" (file flags callback))
269
270(defun file-notify--add-watch-inotify (_file dir flags)
271 "Add a watch for FILE in DIR with FLAGS, using inotify."
272 (inotify-add-watch dir
273 (append
274 (and (memq 'change flags)
275 '(create delete delete-self modify move-self move))
276 (and (memq 'attribute-change flags)
277 '(attrib)))
278 #'file-notify-callback))
279
280(defun file-notify--add-watch-kqueue (file _dir flags)
281 "Add a watch for FILE in DIR with FLAGS, using kqueue."
282 ;; kqueue does not report changes to file contents when watching
283 ;; directories, so we watch each file directly.
284 (kqueue-add-watch file
285 (append
286 (and (memq 'change flags)
287 '(create delete write extend rename))
288 (and (memq 'attribute-change flags)
289 '(attrib)))
290 #'file-notify-callback))
291
292(defun file-notify--add-watch-w32notify (_file dir flags)
293 "Add a watch for FILE in DIR with FLAGS, using w32notify."
294 (w32notify-add-watch dir
295 (append
296 (and (memq 'change flags)
297 '(file-name directory-name size last-write-time))
298 (and (memq 'attribute-change flags)
299 '(attributes)))
300 #'file-notify-callback))
301
302(defun file-notify--add-watch-gfilenotify (_file dir flags)
303 "Add a watch for FILE in DIR with FLAGS, using gfilenotify."
304 (gfile-add-watch dir
305 (append '(watch-mounts send-moved) flags)
306 #'file-notify-callback))
307
268(defun file-notify-add-watch (file flags callback) 308(defun file-notify-add-watch (file flags callback)
269 "Add a watch for filesystem events pertaining to FILE. 309 "Add a watch for filesystem events pertaining to FILE.
270This arranges for filesystem events pertaining to FILE to be reported 310This arranges for filesystem events pertaining to FILE to be reported
@@ -315,70 +355,34 @@ FILE is the name of the file whose event is being reported."
315 (dir (directory-file-name 355 (dir (directory-file-name
316 (if (file-directory-p file) 356 (if (file-directory-p file)
317 file 357 file
318 (file-name-directory file)))) 358 (file-name-directory file)))))
319 desc func l-flags)
320 359
321 (unless (file-directory-p dir) 360 (unless (file-directory-p dir)
322 (signal 'file-notify-error `("Directory does not exist" ,dir))) 361 (signal 'file-notify-error `("Directory does not exist" ,dir)))
323 362
324 (if handler 363 (let ((desc
325 ;; A file name handler could exist even if there is no local 364 (if handler
326 ;; file notification support. 365 (funcall handler 'file-notify-add-watch dir flags callback)
327 (setq desc (funcall handler 'file-notify-add-watch dir flags callback)) 366 (funcall
328 367 (pcase file-notify--library
329 ;; Check, whether Emacs has been compiled with file notification 368 ('inotify #'file-notify--add-watch-inotify)
330 ;; support. 369 ('kqueue #'file-notify--add-watch-kqueue)
331 (unless file-notify--library 370 ('w32notify #'file-notify--add-watch-w32notify)
332 (signal 'file-notify-error 371 ('gfilenotify #'file-notify--add-watch-gfilenotify)
333 '("No file notification package available"))) 372 (_ (signal 'file-notify-error
334 373 '("No file notification package available"))))
335 ;; Determine low-level function to be called. 374 file dir flags))))
336 (setq func 375
337 (cond 376 ;; Modify `file-notify-descriptors'.
338 ((eq file-notify--library 'inotify) 'inotify-add-watch) 377 (let ((watch (file-notify--watch-make
339 ((eq file-notify--library 'kqueue) 'kqueue-add-watch) 378 ;; We do not want to enter quoted file names into the hash.
340 ((eq file-notify--library 'gfilenotify) 'gfile-add-watch) 379 (file-name-unquote dir)
341 ((eq file-notify--library 'w32notify) 'w32notify-add-watch))) 380 (unless (file-directory-p file)
342 381 (file-name-nondirectory file))
343 ;; Determine respective flags. 382 callback)))
344 (if (eq file-notify--library 'gfilenotify) 383 (puthash desc watch file-notify-descriptors))
345 (setq l-flags (append '(watch-mounts send-moved) flags)) 384 ;; Return descriptor.
346 (when (memq 'change flags) 385 desc)))
347 (setq
348 l-flags
349 (cond
350 ((eq file-notify--library 'inotify)
351 '(create delete delete-self modify move-self move))
352 ((eq file-notify--library 'kqueue)
353 '(create delete write extend rename))
354 ((eq file-notify--library 'w32notify)
355 '(file-name directory-name size last-write-time)))))
356 (when (memq 'attribute-change flags)
357 (push (cond
358 ((eq file-notify--library 'inotify) 'attrib)
359 ((eq file-notify--library 'kqueue) 'attrib)
360 ((eq file-notify--library 'w32notify) 'attributes))
361 l-flags)))
362
363 ;; Call low-level function.
364 (setq desc (funcall
365 ;; kqueue does not report file changes in directory
366 ;; monitor. So we must watch the file itself.
367 func (if (eq file-notify--library 'kqueue) file dir)
368 l-flags 'file-notify-callback)))
369
370 ;; We do not want to enter quoted file names into the hash.
371 (setq file (file-name-unquote file)
372 dir (file-name-unquote dir))
373
374 ;; Modify `file-notify-descriptors'.
375 (let ((watch (file-notify--watch-make
376 dir
377 (unless (file-directory-p file) (file-name-nondirectory file))
378 callback)))
379 (puthash desc watch file-notify-descriptors))
380 ;; Return descriptor.
381 desc))
382 386
383(defun file-notify-rm-watch (descriptor) 387(defun file-notify-rm-watch (descriptor)
384 "Remove an existing watch specified by its DESCRIPTOR. 388 "Remove an existing watch specified by its DESCRIPTOR.