File notifications report unmount events (bug#66381)

* doc/lispref/os.texi (File Notifications): Unmounting a watched
filesystem is reported now.

* etc/NEWS: File notifications report unmount events now.
Fix typos.

* lisp/filenotify.el (file-notify--callback-inotify)
(file-notify--add-watch-inotify): Handle `unmount'.
(file-notify--callback-kqueue, file-notify--add-watch-kqueue):
Handle `revoke'.
(file-notify--callback-gfilenotify): Handle `unmounted'.
(file-notify-callback): Handle `unmount' and `unmounted'.
(file-notify--add-watch-inotify):

* lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-notify-add-watch):
Handle `unmounted'.

* lisp/net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch):
Handle `unmount' and `unmounted'.

* src/gfilenotify.c (dir_monitor_callback): Handle Qunmounted.

* src/inotify.c (symbol_to_inotifymask): Handle IN_IGNORED and
IN_UNMOUNT.

* src/kqueue.c (kqueue_callback, Fkqueue_add_watch):
Handle NOTE_REVOKE.
(Fkqueue_add_watch): Adapt docstring.
(syms_of_kqueue): Declare `revoke.
This commit is contained in:
Michael Albinus 2023-10-10 19:51:22 +02:00
parent 294567d171
commit f7185ca29b
8 changed files with 59 additions and 35 deletions

View file

@ -3355,7 +3355,8 @@ reliably report file attribute changes when watching a directory.
The @code{stopped} event means that watching the file has been
discontinued. This could be because @code{file-notify-rm-watch} was
called (see below), or because the file being watched was deleted, or
due to another error reported from the underlying library which makes
because the filesystem of the file being watched was unmounted, or due
to another error reported from the underlying library which makes
further watching impossible.
@var{file} and @var{file1} are the name of the file(s) whose event is

View file

@ -144,9 +144,7 @@ can use this to distinguish between buffers visiting files with the
same base name that belong to different projects by using the provided
transform function 'project-uniquify-dirname-transform'.
** 'insert-directory-program' is now a defcustom.
** 'insert-directory-program' prefers "gls" on *BSD and macOS.
** 'insert-directory-program' is now a user option.
On *BSD and macOS systems, this user option now defaults to the "gls"
executable, if it exists. This should remove the need to change its
value when installing GNU coreutils using something like ports or
@ -267,6 +265,7 @@ functions in CJK locales.
* Changes in Specialized Modes and Packages in Emacs 30.1
** gdb-mi
---
*** Variable order and truncation can now be configured in 'gdb-many-windows'.
The new user option 'gdb-locals-table-row-config' allows users to
@ -285,7 +284,7 @@ If you want to get back the old behavior, set the user option to the value
---
*** New user option 'gdb-display-io-buffer'.
If this is nil, "M-x gdb" will neither create nor display a separate
If this is nil, 'M-x gdb' will neither create nor display a separate
buffer for the I/O of the program being debugged, but will instead
redirect the program's interaction to the GDB execution buffer. The
default is t, to preserve previous behavior.
@ -299,9 +298,9 @@ equivalent to the "--heading" option of some tools such as 'git grep'
and 'rg'. The headings are displayed using the new 'grep-heading'
face.
---
** Compilation mode
---
*** The 'omake' matching rule is now disabled by default.
This is because it partly acts by modifying other rules which may
occasionally be surprising. It can be re-enabled by adding 'omake' to
@ -548,6 +547,11 @@ buffer must either visit a file, or it must run 'dired-mode'. Another
method but "sudo" can be configured with user option
'tramp-file-name-with-method'.
** File Notifications
+++
*** All backends except w32notify detect unmounting of a watched filesystem now.
** EWW
+++
@ -809,7 +813,8 @@ You can now configure how a thumbnail is named using this option.
** ERT
*** New macro `skip-when' to skip 'ert-deftest' tests.
+++
*** New macro 'skip-when' to skip 'ert-deftest' tests.
This can help avoid some awkward skip conditions. For example
'(skip-unless (not noninteractive))' can be changed to the easier
to read '(skip-when noninteractive)'.
@ -831,18 +836,19 @@ neither of which have been supported by Emacs since version 23.1.
The user option 'url-gateway-nslookup-program' and the function
'url-gateway-nslookup-host' are consequently also obsolete.
+++
** Edmacro
+++
*** New command 'edmacro-set-macro-to-region-lines'.
Bound to 'C-c C-r', this command replaces the macro text with the
lines of the region. If needed, the region is extended to include
whole lines. If the region ends at the beginning of a line, that last
line is excluded.
+++
*** New user option 'edmacro-reverse-macro-lines'.
When this is non-nil, the lines of key sequences are displayed with
the most recent line fist. This is can be useful when working with
the most recent line first. This is can be useful when working with
macros with many lines, such as from 'kmacro-edit-lossage'.
@ -861,8 +867,11 @@ A major mode based on the tree-sitter library for editing HEEx files.
---
*** New major mode 'elixir-ts-mode'.
A major mode based on the tree-sitter library for editing Elixir
files.
A major mode based on the tree-sitter library for editing Elixir files.
---
*** New major mode 'lua-ts-mode'.
A major mode based on the tree-sitter library for editing Lua files.
+++
** New global minor mode 'minibuffer-regexp-mode'.
@ -871,10 +880,6 @@ It highlights parens via show-paren-mode and blink-matching-paren in
a user-friendly way, avoids reporting alleged paren mismatches and makes
sexp navigation more intuitive.
---
*** New major mode 'lua-ts-mode'.
A major mode based on the tree-sitter library for editing Lua files.
---
** The highly accessible Modus themes collection has eight items.
The 'modus-operandi' and 'modus-vivendi' are the main themes that have
@ -913,7 +918,7 @@ the file listing's performance is still optimized.
* Incompatible Lisp Changes in Emacs 30.1
** 'post-gc-hook' runs after updating 'gcs-done' and `'gcs-elapsed'.
** 'post-gc-hook' runs after updating 'gcs-done' and 'gcs-elapsed'.
---
** The escape sequence '\x' not followed by hex digits is now an error.

View file

@ -138,7 +138,7 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.")
((memq action '(delete delete-self move-self)) 'deleted)
((eq action 'moved-from) 'renamed-from)
((eq action 'moved-to) 'renamed-to)
((eq action 'ignored) 'stopped)))
((memq action '(ignored unmount)) 'stopped)))
actions))
file file1-or-cookie))
@ -153,7 +153,8 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.")
((eq action 'write) 'changed)
((memq action '(attrib link)) 'attribute-changed)
((eq action 'delete) 'deleted)
((eq action 'rename) 'renamed)))
((eq action 'rename) 'renamed)
((eq action 'revoke) 'stopped)))
actions))
file file1-or-cookie))
@ -179,7 +180,8 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.")
((memq action
'(created changed attribute-changed deleted))
action)
((eq action 'moved) 'renamed)))
((eq action 'moved) 'renamed)
((eq action 'unmounted) 'stopped)))
(if (consp actions) actions (list actions))))
file file1-or-cookie))
@ -195,6 +197,7 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.")
((memq action '(created changed attribute-changed deleted))
action)
((eq action 'moved) 'renamed)
((eq action 'unmounted) 'stopped)
;; inotify actions:
((eq action 'create) 'created)
((eq action 'modify) 'changed)
@ -202,7 +205,7 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.")
((memq action '(delete delete-self move-self)) 'deleted)
((eq action 'moved-from) 'renamed-from)
((eq action 'moved-to) 'renamed-to)
((eq action 'ignored) 'stopped)))
((memq action '(ignored unmount)) 'stopped)))
(if (consp actions) actions (list actions))))
file file1-or-cookie))
@ -339,7 +342,7 @@ DESC is the back-end descriptor. ACTIONS is a list of:
"Add a watch for FILE in DIR with FLAGS, using inotify."
(inotify-add-watch dir
(append
'(dont-follow)
'(dont-follow ignored unmount)
(and (memq 'change flags)
'(create delete delete-self modify move-self move))
(and (memq 'attribute-change flags)
@ -352,6 +355,7 @@ DESC is the back-end descriptor. ACTIONS is a list of:
;; directories, so we watch each file directly.
(kqueue-add-watch file
(append
'(revoke)
(and (memq 'change flags)
'(create delete write extend rename))
(and (memq 'attribute-change flags)

View file

@ -1490,10 +1490,10 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(cond
((and (memq 'change flags) (memq 'attribute-change flags))
'(created changed changes-done-hint moved deleted
attribute-changed))
attribute-changed unmounted))
((memq 'change flags)
'(created changed changes-done-hint moved deleted))
((memq 'attribute-change flags) '(attribute-changed))))
'(created changed changes-done-hint moved deleted unmounted))
((memq 'attribute-change flags) '(attribute-changed unmounted))))
(p (apply
#'start-process
"gvfs-monitor" (generate-new-buffer " *gvfs-monitor*")

View file

@ -3802,11 +3802,12 @@ Fall back to normal file name handler if no Tramp handler exists."
(cond
((and (memq 'change flags) (memq 'attribute-change flags))
(concat "create,modify,move,moved_from,moved_to,move_self,"
"delete,delete_self,attrib,ignored"))
"delete,delete_self,attrib"))
((memq 'change flags)
(concat "create,modify,move,moved_from,moved_to,move_self,"
"delete,delete_self,ignored"))
((memq 'attribute-change flags) "attrib,ignored"))
"delete,delete_self"))
((memq 'attribute-change flags) "attrib"))
events (concat events ",ignored,unmount")
;; "-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.
@ -3821,10 +3822,10 @@ Fall back to normal file name handler if no Tramp handler exists."
(cond
((and (memq 'change flags) (memq 'attribute-change flags))
'(created changed changes-done-hint moved deleted
attribute-changed))
attribute-changed unmounted))
((memq 'change flags)
'(created changed changes-done-hint moved deleted))
((memq 'attribute-change flags) '(attribute-changed)))
'(created changed changes-done-hint moved deleted unmounted))
((memq 'attribute-change flags) '(attribute-changed unmounted)))
sequence `(,command "monitor" ,localname)))
;; None.
(t (tramp-error

View file

@ -88,7 +88,9 @@ dir_monitor_callback (GFileMonitor *monitor,
&& !NILP (Fmember (symbol, list5 (Qchanged, Qchanges_done_hint,
Qdeleted, Qcreated, Qmoved))))
|| (!NILP (Fmember (Qattribute_change, flags))
&& EQ (symbol, Qattribute_changed)))
&& EQ (symbol, Qattribute_changed))
|| (!NILP (Fmember (Qwatch_mounts, flags))
&& EQ (symbol, Qunmounted)))
{
/* Construct an event. */
EVENT_INIT (event);
@ -105,8 +107,8 @@ dir_monitor_callback (GFileMonitor *monitor,
/* XD_DEBUG_MESSAGE ("%s", XD_OBJECT_TO_STRING (event.arg)); */
}
/* Cancel monitor if file or directory is deleted. */
if (!NILP (Fmember (symbol, list2 (Qdeleted, Qmoved)))
/* Cancel monitor if file or directory is deleted or unmounted. */
if (!NILP (Fmember (symbol, list3 (Qdeleted, Qmoved, Qunmounted)))
&& strcmp (name, SSDATA (XCAR (XCDR (watch_object)))) == 0
&& !g_file_monitor_is_cancelled (monitor))
g_file_monitor_cancel (monitor);

View file

@ -148,6 +148,11 @@ symbol_to_inotifymask (Lisp_Object symb)
else if (EQ (symb, Qonlydir))
return IN_ONLYDIR;
else if (EQ (symb, Qignored))
return IN_IGNORED;
else if (EQ (symb, Qunmount))
return IN_UNMOUNT;
else if (EQ (symb, Qt) || EQ (symb, Qall_events))
return IN_ALL_EVENTS;
else

View file

@ -320,13 +320,16 @@ kqueue_callback (int fd, void *data)
directory is monitored. */
if (kev.fflags & NOTE_RENAME)
actions = Fcons (Qrename, actions);
if (kev.fflags & NOTE_REVOKE)
actions = Fcons (Qrevoke, actions);
/* Create the event. */
if (! NILP (actions))
kqueue_generate_event (watch_object, actions, file, Qnil);
/* Cancel monitor if file or directory is deleted or renamed. */
if (kev.fflags & (NOTE_DELETE | NOTE_RENAME))
/* Cancel monitor if file or directory is deleted or renamed or
the file system is unmounted. */
if (kev.fflags & (NOTE_DELETE | NOTE_RENAME | NOTE_REVOKE))
Fkqueue_rm_watch (descriptor);
}
return;
@ -351,6 +354,7 @@ following symbols:
`attrib' -- a FILE attribute was changed
`link' -- a FILE's link count was changed
`rename' -- FILE was moved to FILE1
`revoke' -- FILE was unmounted
When any event happens, Emacs will call the CALLBACK function passing
it a single argument EVENT, which is of the form
@ -437,6 +441,7 @@ only when the upper directory of the renamed file is watched. */)
if (! NILP (Fmember (Qattrib, flags))) fflags |= NOTE_ATTRIB;
if (! NILP (Fmember (Qlink, flags))) fflags |= NOTE_LINK;
if (! NILP (Fmember (Qrename, flags))) fflags |= NOTE_RENAME;
if (! NILP (Fmember (Qrevoke, flags))) fflags |= NOTE_REVOKE;
/* Register event. */
EV_SET (&kev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
@ -526,6 +531,7 @@ syms_of_kqueue (void)
DEFSYM (Qattrib, "attrib"); /* NOTE_ATTRIB */
DEFSYM (Qlink, "link"); /* NOTE_LINK */
DEFSYM (Qrename, "rename"); /* NOTE_RENAME */
DEFSYM (Qrevoke, "revoke"); /* NOTE_REVOKE */
staticpro (&watch_list);