Repository: hannobraun/inotify-rs (language: rust)

Issue:
Improve documentation of `Inotify::add_watch`
`Inotify::add_watch` can not only be used to create a new watch. It can also modify an already existing watch. This will happen, if `add_watch` is called with a path it has already been called with before, or if it is called with any path that refers to an inode that is already being watched.

Modifying an existing watch will not allocate a new watch descriptor and will return an existing one instead.

Since this behavior can be highly unexpected, especially in the presence of hardlinks, it should be highlighted in the documentation.


Discussion / hints:

Fix patch:
diff --git a/inotify/src/lib.rs b/inotify/src/lib.rs
index 2bf1658..ac95afb 100644
--- a/inotify/src/lib.rs
+++ b/inotify/src/lib.rs
@@ -157,20 +157,43 @@ impl Inotify {
         }
     }
 
-    /// Watches the file at the given path
+    /// Adds or updates a watch for the given path
     ///
-    /// Adds a watch for the file at the given path by calling
-    /// [`inotify_add_watch`]. Returns a watch descriptor that can be used to
-    /// refer to this watch later.
+    /// Adds a new watch or updates an existing one for the file referred to by
+    /// `path`. Returns a watch descriptor that can be used to refer to this
+    /// watch later.
     ///
     /// The `mask` argument defines what kind of changes the file should be
     /// watched for, and how to do that. See the documentation of [`WatchMask`]
     /// for details.
     ///
+    /// If this method is used to add a new watch, a new `WatchDescriptor` is
+    /// returned. If it is used to update an existing watch, the same
+    /// `WatchDescriptor` for that existing watch is returned.
+    ///
+    /// Under the hood, this method just calls [`inotify_add_watch`] and does
+    /// some trivial translation between the types on the Rust side and the C
+    /// side.
+    ///
+    /// # Attention: Updating watches and hardlinks
+    ///
+    /// As mentioned above, this method can be used to update an existing watch.
+    /// This is usually done by calling this method with the same `path`
+    /// argument that it has been called with before. But less obviously, it can
+    /// also happen if the method is called with a different path that happens
+    /// to link to the same inode.
+    ///
+    /// You can detect this by keeping track of `WatchDescriptor`s and the paths
+    /// they have been returned for. If the same `WatchDescriptor` is returned
+    /// for a different path (and you haven't freed the `WatchDescriptor` by
+    /// removing the watch), you know you have two paths pointing to the same
+    /// inode, and therefore being watched by the same watch.
+    ///
     /// # Errors
     ///
-    /// Directly returns the error from the call to [`inotify_add_watch`],
-    /// without adding any error conditions of its own.
+    /// Directly returns the error from the call to [`inotify_add_watch`]
+    /// (translated into an `io::Error`), without adding any error conditions of
+    /// its own.
     ///
     /// # Examples
     ///


Test patch: