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 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,
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, 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/>.
*/
/*
*/
#include "includes.h"
+#include "../librpc/gen_ndr/notify.h"
+#include "smbd/smbd.h"
#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)
*/
{
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
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",
return True;
}
-
+
/*
dispatch one inotify event
-
+
the cookies are used to correctly handle renames
*/
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) &&
int bufsize = 0;
struct inotify_event *e0, *e;
uint32_t prev_cookie=0;
+ NTSTATUS status;
/*
we must use FIONREAD as we cannot predict the length of the
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);
+ e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize + 1);
if (e == NULL) return;
+ ((uint8_t *)e)[bufsize] = '\0';
- if (read(in->fd, e0, bufsize) != bufsize) {
- DEBUG(0,("Failed to read all inotify data\n"));
+ status = read_data(in->fd, (char *)e0, bufsize);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to read all inotify data - %s\n",
+ nt_errstr(status)));
talloc_free(e0);
+ /* the inotify fd will now be out of sync,
+ * can't keep reading data off it */
+ TALLOC_FREE(fde);
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)) {
/* 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;
}
DEBUG(1, ("inotify_rm_watch returned %s\n",
strerror(errno)));
}
-
+
}
return 0;
}
/* the caller frees the handle to stop watching */
talloc_set_destructor(w, watch_destructor);
-
+
return NT_STATUS_OK;
}