tKeep watching files sending IN_IGNORED - wendy - watch files/directories and run commands on any event
 (HTM) git clone git://z3bra.org/wendy
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 586f632bf3e8d3e7155542e56cfc6c28e7d2ece1
 (DIR) parent 01b58f2fc1d014c7c4e6d02aa65997f52855c91c
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Sun, 31 Jan 2016 16:52:09 +0100
       
       Keep watching files sending IN_IGNORED
       
       In case a file gets deleted, we remove it from our watch list, and try
       tto add it again, it case it has been recreated. This will handle case
       where the file is deleted, and then recreated, for example with
       rename(2).
       
       Diffstat:
         M wendy.c                             |      49 +++++++++++++++++++++----------
       
       1 file changed, 33 insertions(+), 16 deletions(-)
       ---
 (DIR) diff --git a/wendy.c b/wendy.c
       t@@ -126,9 +126,26 @@ add_node(int wd, const char *path)
                n->next = head ? head : NULL;
                head = n;
        
       +        nb++;
                return n;
        }
        
       +int
       +del_node(int wd)
       +{
       +        struct node_t *n, *p;
       +        p = n = head;
       +        while (n && n->wd != wd) {
       +                p = n;
       +                n = n->next;
       +        }
       +
       +        p->next = n->next;
       +        free(n);
       +        nb--;
       +        return 0;
       +}
       +
        const char *
        wd_path(int wd)
        {
       t@@ -152,12 +169,10 @@ watch_node(int fd, const char *path, uint32_t mask)
                wd  = inotify_add_watch(fd, path, mask);
                if (wd < 0) {
                        perror("inotify_add_watch");
       -                exit(1);
       +                return wd;
                }
        
                add_node(wd, path);
       -        nb++;
       -
                return wd;
        }
        
       t@@ -226,20 +241,22 @@ main (int argc, char **argv)
                                /* get events one by one */
                                ev = (struct inotify_event *) &buf[i];
        
       +                        /*
       +                         * IN_IGNORED is triggered when a file watched
       +                         * doesn't exists anymore. In this case we
       +                         * delete the node we were watching, and try to
       +                         * watch the file again. If that fails, then the 'nb'
       +                         * variable will be decremented, so that wendy can terminate
       +                         * when there is no more files to watch.
       +                         */
       +                        if (ev->mask & IN_IGNORED) {
       +                                del_node(ev->wd);
       +                                if (watch_node(fd, EVENT_PATH(ev), mask) < 0 && verbose)
       +                                        fprintf(stderr, "%s: watch removed\n", EVENT_PATH(ev));
       +                        }
       +
                                if (verbose) {
       -                                /*
       -                                 * IN_IGNORED is triggered when a file watched
       -                                 * doesn't exists anymore. In this case we
       -                                 * decrement the number of files watched so
       -                                 * that if there is none remaining, wendy will
       -                                 * terminate.
       -                                 */
       -                                if (ev->mask & IN_IGNORED) {
       -                                        fprintf(stderr, "%s: removing watch\n", EVENT_PATH(ev));
       -                                        nb--;
       -                                } else {
       -                                        printf("%u\t%s\n", ev->mask, EVENT_PATH(ev));
       -                                }
       +                                printf("%u\t%s\n", ev->mask, EVENT_PATH(ev));
                                        fflush(stdout);
                                }