]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail -F: don't stop following the target of a rename
authorGiuseppe Scrivano <gscrivano@gnu.org>
Tue, 29 Dec 2009 23:20:24 +0000 (00:20 +0100)
committerJim Meyering <meyering@redhat.com>
Wed, 30 Dec 2009 10:22:55 +0000 (11:22 +0100)
This fixes a bug whereby tail -F would fail to track changes
to a file that was a target of a rename, and when the source of
the rename was another tailed file.

* src/tail.c (tail_forever_inotify): Ensure the wd is not already
present in the hash table before trying to add it.  When a new watch
descriptor is added to the `wd_to_name' hash table, check that it is
not already present.  If it is present then remove the previous element.

src/tail.c

index 3d5e2212f11f946b25225c0f87c9a40df6d4dda6..28a0e26a969cee74159bcbd35a7b3c28fb911a74 100644 (file)
@@ -1486,11 +1486,24 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
           /* Remove `fspec' and re-add it using `new_fd' as its key.  */
           hash_delete (wd_to_name, fspec);
           fspec->wd = new_wd;
+
+          /* If the file was moved then inotify will use the source file wd for
+             the destination file.  Make sure the key is not present in the
+             table.  */
+          struct File_spec *prev = hash_delete (wd_to_name, fspec);
+          if (prev && prev != fspec)
+            {
+              if (follow_mode == Follow_name)
+                recheck (prev, false);
+              prev->wd = -1;
+              close_fd (prev->fd, pretty_name (prev));
+            }
+
           if (hash_insert (wd_to_name, fspec) == NULL)
             xalloc_die ();
 
           if (follow_mode == Follow_name)
-            recheck (&(f[j]), false);
+            recheck (fspec, false);
         }
       else
         {