]> git.eshelyaron.com Git - emacs.git/commitdiff
File notifications report unmount events (bug#66381)
authorMichael Albinus <michael.albinus@gmx.de>
Tue, 10 Oct 2023 17:51:22 +0000 (19:51 +0200)
committerMichael Albinus <michael.albinus@gmx.de>
Tue, 10 Oct 2023 17:51:22 +0000 (19:51 +0200)
* 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.

doc/lispref/os.texi
etc/NEWS
lisp/filenotify.el
lisp/net/tramp-gvfs.el
lisp/net/tramp-sh.el
src/gfilenotify.c
src/inotify.c
src/kqueue.c

index 5400d492f0a22c0fc0c76391a9096c93df686998..f92709f1f9bd9d5765166fc7f407e996ca7f1553 100644 (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
index 70110768c9717853efb32d870cae80f517e19bc5..ececb7e8459b49da3c26b0995348af1f698541a3 100644 (file)
--- a/etc/NEWS
+++ b/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'.
 
 \f
@@ -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.
 \f
 * 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.
index e9f8d4e515d9f852bd6f743f0add3918d3dd62cf..03bd4e5148542c76abbc4b5f2c21f256a370ef04 100644 (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)
index 577760f806c33e5c91231071575296461ebc7467..227571b148b12e8a4c34d71a88836178623be44b 100644 (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*")
index 95c27626166dd74ca907e0f94c91d428adf07d76..4a5840cca4c92ff3160d9f5bb6320c0d7229094a 100644 (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
index de09ffe5fd33d27b9ff53e79a98c49c4eecae3ca..3dd6390db10384a014a5f97dcc53f743daa18112 100644 (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);
index 105ff5a9d8a6b492fa92dda2bb756cd074ace603..247d9f03055587e701172125337fd4f36686aae7 100644 (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
index 22c279b7ce3e9f903be7bfb4e87e4cf093122c62..43d5f40624b334a0940a1711dec52e790dc7eb4a 100644 (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);