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:
parent
294567d171
commit
f7185ca29b
8 changed files with 59 additions and 35 deletions
|
@ -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
|
||||
|
|
35
etc/NEWS
35
etc/NEWS
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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*")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
10
src/kqueue.c
10
src/kqueue.c
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue