Fix include paths to new location of libutil.
[bbaumbach/samba-autobuild/.git] / source4 / ntvfs / sysdep / inotify.c
index a5104a01d022a2b824e6051114a488ef765c457e..e4e7c446866718a034ca6f66bfe3a5020c976445 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
@@ -26,8 +25,9 @@
 #include "system/filesys.h"
 #include "ntvfs/sysdep/sys_notify.h"
 #include "lib/events/events.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "libcli/raw/smb.h"
+#include "param/param.h"
 
 #include <linux/inotify.h>
 #include <asm/unistd.h>
@@ -64,47 +64,38 @@ static int inotify_rm_watch(int fd, int wd)
 struct inotify_private {
        struct sys_notify_context *ctx;
        int fd;
-       struct watch_context *watches;
+       struct inotify_watch_context *watches;
 };
 
-struct watch_context {
-       struct watch_context *next, *prev;
+struct inotify_watch_context {
+       struct inotify_watch_context *next, *prev;
        struct inotify_private *in;
        int wd;
        sys_notify_callback_t callback;
-       void *private;
+       void *private_data;
        uint32_t mask; /* the inotify mask */
        uint32_t filter; /* the windows completion filter */
        const char *path;
 };
 
 
-/*
-  destroy the inotify private context
-*/
-static int inotify_destructor(struct inotify_private *in)
-{
-       close(in->fd);
-       return 0;
-}
-
-
 /*
   see if a particular event from inotify really does match a requested
   notify event in SMB
 */
-static BOOL filter_match(struct watch_context *w, struct inotify_event *e)
+static bool filter_match(struct inotify_watch_context *w,
+                        struct inotify_event *e)
 {
        if ((e->mask & w->mask) == 0) {
                /* this happens because inotify_add_watch() coalesces watches on the same
                   path, oring their masks together */
-               return False;
+               return false;
        }
 
        /* SMB separates the filters for files and directories */
        if (e->mask & IN_ISDIR) {
                if ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) == 0) {
-                       return False;
+                       return false;
                }
        } else {
                if ((e->mask & IN_ATTRIB) &&
@@ -113,18 +104,18 @@ static BOOL filter_match(struct watch_context *w, struct inotify_event *e)
                                  FILE_NOTIFY_CHANGE_LAST_ACCESS|
                                  FILE_NOTIFY_CHANGE_EA|
                                  FILE_NOTIFY_CHANGE_SECURITY))) {
-                       return True;
+                       return true;
                }
                if ((e->mask & IN_MODIFY) && 
                    (w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) {
-                       return True;
+                       return true;
                }
                if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) {
-                       return False;
+                       return false;
                }
        }
 
-       return True;
+       return true;
 }
        
 
@@ -139,7 +130,7 @@ static void inotify_dispatch(struct inotify_private *in,
                             uint32_t prev_cookie,
                             struct inotify_event *e2)
 {
-       struct watch_context *w, *next;
+       struct inotify_watch_context *w, *next;
        struct notify_event ne;
 
        /* ignore extraneous events, such as unmount and IN_IGNORED events */
@@ -175,7 +166,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)) {
-                       w->callback(in->ctx, w->private, &ne);
+                       w->callback(in->ctx, w->private_data, &ne);
                }
        }
 
@@ -194,7 +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)) {
-                       w->callback(in->ctx, w->private, &ne);
+                       w->callback(in->ctx, w->private_data, &ne);
                }
        }
 }
@@ -203,9 +194,10 @@ static void inotify_dispatch(struct inotify_private *in,
   called when the kernel has some events for us
 */
 static void inotify_handler(struct event_context *ev, struct fd_event *fde,
-                           uint16_t flags, void *private)
+                           uint16_t flags, void *private_data)
 {
-       struct inotify_private *in = talloc_get_type(private, struct inotify_private);
+       struct inotify_private *in = talloc_get_type(private_data,
+                                                    struct inotify_private);
        int bufsize = 0;
        struct inotify_event *e0, *e;
        uint32_t prev_cookie=0;
@@ -252,11 +244,6 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde,
 static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
 {
        struct inotify_private *in;
-
-       if (!lp_parm_bool(-1, "notify", "inotify", True)) {
-               return NT_STATUS_INVALID_SYSTEM_SERVICE;
-       }
-
        in = talloc(ctx, struct inotify_private);
        NT_STATUS_HAVE_NO_MEMORY(in);
        in->fd = inotify_init();
@@ -268,11 +255,10 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
        in->ctx = ctx;
        in->watches = NULL;
 
-       ctx->private = in;
-       talloc_set_destructor(in, inotify_destructor);
+       ctx->private_data = in;
 
        /* add a event waiting for the inotify fd to be readable */
-       event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ, inotify_handler, in);
+       event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, inotify_handler, in);
        
        return NT_STATUS_OK;
 }
@@ -311,7 +297,7 @@ static uint32_t inotify_map(struct notify_entry *e)
 /*
   destroy a watch
 */
-static int watch_destructor(struct watch_context *w)
+static int watch_destructor(struct inotify_watch_context *w)
 {
        struct inotify_private *in = w->in;
        int wd = w->wd;
@@ -332,24 +318,31 @@ static int watch_destructor(struct watch_context *w)
   add a watch. The watch is removed when the caller calls
   talloc_free() on *handle
 */
-static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entry *e,
-                             sys_notify_callback_t callback, void *private, 
-                             void **handle)
+static NTSTATUS inotify_watch(struct sys_notify_context *ctx,
+                             struct notify_entry *e,
+                             sys_notify_callback_t callback,
+                             void *private_data, 
+                             void *handle_p)
 {
        struct inotify_private *in;
        int wd;
        uint32_t mask;
-       struct watch_context *w;
+       struct inotify_watch_context *w;
        uint32_t filter = e->filter;
+       void **handle = (void **)handle_p;
 
        /* maybe setup the inotify fd */
-       if (ctx->private == NULL) {
+       if (ctx->private_data == NULL) {
                NTSTATUS status;
+               if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) {
+                       return NT_STATUS_INVALID_SYSTEM_SERVICE;
+               }
+
                status = inotify_setup(ctx);
                NT_STATUS_NOT_OK_RETURN(status);
        }
 
-       in = talloc_get_type(ctx->private, struct inotify_private);
+       in = talloc_get_type(ctx->private_data, struct inotify_private);
 
        mask = inotify_map(e);
        if (mask == 0) {
@@ -368,7 +361,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entr
                return map_nt_error_from_unix(errno);
        }
 
-       w = talloc(in, struct watch_context);
+       w = talloc(in, struct inotify_watch_context);
        if (w == NULL) {
                inotify_rm_watch(in->fd, wd);
                e->filter = filter;
@@ -378,7 +371,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entr
        w->in = in;
        w->wd = wd;
        w->callback = callback;
-       w->private = private;
+       w->private_data = private_data;
        w->mask = mask;
        w->filter = filter;
        w->path = talloc_strdup(w, e->path);