Stop listening for inotify data when there's none
[metze/samba/wip.git] / source3 / smbd / notify_inotify.c
index f332e4b3d24bd202aef93f414998d2b4e2e6d73a..26570a22162d5facef1536216dec317934c7b326 100644 (file)
@@ -2,17 +2,17 @@
    Unix SMB/CIFS implementation.
 
    Copyright (C) Andrew Tridgell 2006
-   
+
    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 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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, see <http://www.gnu.org/licenses/>.
 */
 
 #ifdef HAVE_INOTIFY
 
+#if HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#else
+
 #ifdef HAVE_ASM_TYPES_H
 #include <asm/types.h>
 #endif
 
+#ifndef HAVE_INOTIFY_INIT
+
 #include <linux/inotify.h>
 #include <asm/unistd.h>
 
-#ifndef HAVE_INOTIFY_INIT
+
 /*
   glibc doesn't define these functions yet (as of March 2006)
 */
@@ -50,8 +56,12 @@ static int inotify_rm_watch(int fd, int wd)
 {
        return syscall(__NR_inotify_rm_watch, fd, wd);
 }
-#endif
+#else
 
+#include <sys/inotify.h>
+
+#endif
+#endif
 
 /* older glibc headers don't have these defines either */
 #ifndef IN_ONLYDIR
@@ -95,7 +105,7 @@ static int inotify_destructor(struct inotify_private *in)
   see if a particular event from inotify really does match a requested
   notify event in SMB
 */
-static BOOL filter_match(struct inotify_watch_context *w,
+static bool filter_match(struct inotify_watch_context *w,
                         struct inotify_event *e)
 {
        DEBUG(10, ("filter_match: e->mask=%x, w->mask=%x, w->filter=%x\n",
@@ -132,12 +142,12 @@ static BOOL filter_match(struct inotify_watch_context *w,
 
        return True;
 }
-       
+
 
 
 /*
   dispatch one inotify event
-  
+
   the cookies are used to correctly handle renames
 */
 static void inotify_dispatch(struct inotify_private *in, 
@@ -201,7 +211,7 @@ static void inotify_dispatch(struct inotify_private *in,
 
        ne.action = NOTIFY_ACTION_MODIFIED;
        e->mask = IN_ATTRIB;
-       
+
        for (w=in->watches;w;w=next) {
                next = w->next;
                if (w->wd == e->wd && filter_match(w, e) &&
@@ -231,20 +241,21 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde,
        if (ioctl(in->fd, FIONREAD, &bufsize) != 0 || 
            bufsize == 0) {
                DEBUG(0,("No data on inotify fd?!\n"));
+               TALLOC_FREE(fde);
                return;
        }
 
        e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize);
        if (e == NULL) return;
 
-       if (read(in->fd, e0, bufsize) != bufsize) {
+       if (sys_read(in->fd, e0, bufsize) != bufsize) {
                DEBUG(0,("Failed to read all inotify data\n"));
                talloc_free(e0);
                return;
        }
 
        /* we can get more than one event in the buffer */
-       while (bufsize >= sizeof(*e)) {
+       while (e && (bufsize >= sizeof(*e))) {
                struct inotify_event *e2 = NULL;
                bufsize -= e->len + sizeof(*e);
                if (bufsize >= sizeof(*e)) {
@@ -286,7 +297,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
 
        /* 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);
-       
+
        return NT_STATUS_OK;
 }
 
@@ -340,7 +351,7 @@ static int watch_destructor(struct inotify_watch_context *w)
                        DEBUG(1, ("inotify_rm_watch returned %s\n",
                                  strerror(errno)));
                }
-               
+
        }
        return 0;
 }
@@ -421,7 +432,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;
 }