notify: Add "dir" to notify_event
[obnox/samba/samba-obnox.git] / source3 / smbd / notify_inotify.c
index b141b9211681e00ba7208bc0c7bad54b4f6b6e04..a3c30f1431e7d1bcb79a0f664ac790cb0ff9a129 100644 (file)
@@ -165,6 +165,7 @@ static void inotify_dispatch(struct inotify_private *in,
        for (w=in->watches;w;w=next) {
                next = w->next;
                if (w->wd == e->wd && filter_match(w, e)) {
+                       ne.dir = w->path;
                        w->callback(in->ctx, w->private_data, &ne);
                }
        }
@@ -184,6 +185,7 @@ static void inotify_dispatch(struct inotify_private *in,
                next = w->next;
                if (w->wd == e->wd && filter_match(w, e) &&
                    !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
+                       ne.dir = w->path;
                        w->callback(in->ctx, w->private_data, &ne);
                }
        }
@@ -324,17 +326,19 @@ static int watch_destructor(struct inotify_watch_context *w)
        int wd = w->wd;
        DLIST_REMOVE(w->in->watches, w);
 
-       /* only rm the watch if its the last one with this wd */
        for (w=in->watches;w;w=w->next) {
-               if (w->wd == wd) break;
-       }
-       if (w == NULL) {
-               DEBUG(10, ("Deleting inotify watch %d\n", wd));
-               if (inotify_rm_watch(in->fd, wd) == -1) {
-                       DEBUG(1, ("inotify_rm_watch returned %s\n",
-                                 strerror(errno)));
+               if (w->wd == wd) {
+                       /*
+                        * Another inotify_watch_context listens on this path,
+                        * leave the kernel level watch in place
+                        */
+                       return 0;
                }
+       }
 
+       DEBUG(10, ("Deleting inotify watch %d\n", wd));
+       if (inotify_rm_watch(in->fd, wd) == -1) {
+               DEBUG(1, ("inotify_rm_watch returned %s\n", strerror(errno)));
        }
        return 0;
 }
@@ -344,15 +348,15 @@ static int watch_destructor(struct inotify_watch_context *w)
   add a watch. The watch is removed when the caller calls
   talloc_free() on *handle
 */
-NTSTATUS inotify_watch(struct sys_notify_context *ctx,
-                      const char *path,
-                      uint32_t *filter,
-                      uint32_t *subdir_filter,
-                      void (*callback)(struct sys_notify_context *ctx, 
-                                       void *private_data,
-                                       struct notify_event *ev),
-                      void *private_data, 
-                      void *handle_p)
+int inotify_watch(struct sys_notify_context *ctx,
+                 const char *path,
+                 uint32_t *filter,
+                 uint32_t *subdir_filter,
+                 void (*callback)(struct sys_notify_context *ctx,
+                                  void *private_data,
+                                  struct notify_event *ev),
+                 void *private_data,
+                 void *handle_p)
 {
        struct inotify_private *in;
        uint32_t mask;
@@ -365,7 +369,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
                int ret;
                ret = inotify_setup(ctx);
                if (ret != 0) {
-                       return map_nt_error_from_unix(ret);
+                       return ret;
                }
        }
 
@@ -374,7 +378,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
        mask = inotify_map(filter);
        if (mask == 0) {
                /* this filter can't be handled by inotify */
-               return NT_STATUS_INVALID_PARAMETER;
+               return EINVAL;
        }
 
        /* using IN_MASK_ADD allows us to cope with inotify() returning the same
@@ -384,7 +388,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
        w = talloc(in, struct inotify_watch_context);
        if (w == NULL) {
                *filter = orig_filter;
-               return NT_STATUS_NO_MEMORY;
+               return ENOMEM;
        }
 
        w->in = in;
@@ -396,7 +400,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
        if (w->path == NULL) {
                *filter = orig_filter;
                TALLOC_FREE(w);
-               return NT_STATUS_NO_MEMORY;
+               return ENOMEM;
        }
 
        /* get a new watch descriptor for this path */
@@ -406,7 +410,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
                *filter = orig_filter;
                TALLOC_FREE(w);
                DEBUG(1, ("inotify_add_watch returned %s\n", strerror(err)));
-               return map_nt_error_from_unix(err);
+               return err;
        }
 
        DEBUG(10, ("inotify_add_watch for %s mask %x returned wd %d\n",
@@ -419,7 +423,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
        /* the caller frees the handle to stop watching */
        talloc_set_destructor(w, watch_destructor);
 
-       return NT_STATUS_OK;
+       return 0;
 }
 
 #endif