You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
977 lines
27 KiB
977 lines
27 KiB
Index: Makefile.in |
|
--- Makefile.in.orig 2008-11-24 16:25:07.000000000 +0100 |
|
+++ Makefile.in 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -309,7 +309,7 @@ |
|
-rm -f libtool |
|
install-pkgconfigDATA: $(pkgconfig_DATA) |
|
@$(NORMAL_INSTALL) |
|
- test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" |
|
+ test -d "$(DESTDIR)$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" |
|
@list='$(pkgconfig_DATA)'; for p in $$list; do \ |
|
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ |
|
f=$(am__strip_dir) \ |
|
Index: libgamin/Makefile.in |
|
--- libgamin/Makefile.in.orig 2008-11-24 16:25:07.000000000 +0100 |
|
+++ libgamin/Makefile.in 2012-07-25 14:05:11.000000000 +0200 |
|
@@ -239,7 +239,7 @@ |
|
gamin_sym.version |
|
|
|
lib_LTLIBRARIES = libgamin-1.la libfam.la |
|
-gaminincludedir = $(includedir)/ |
|
+gaminincludedir = $(includedir) |
|
gamininclude_HEADERS = \ |
|
fam.h |
|
|
|
@@ -302,7 +302,7 @@ |
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
|
install-libLTLIBRARIES: $(lib_LTLIBRARIES) |
|
@$(NORMAL_INSTALL) |
|
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" |
|
+ test -d "$(DESTDIR)$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" |
|
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \ |
|
if test -f $$p; then \ |
|
f=$(am__strip_dir) \ |
|
@@ -383,7 +383,7 @@ |
|
-rm -rf .libs _libs |
|
install-gaminincludeHEADERS: $(gamininclude_HEADERS) |
|
@$(NORMAL_INSTALL) |
|
- test -z "$(gaminincludedir)" || $(MKDIR_P) "$(DESTDIR)$(gaminincludedir)" |
|
+ test -d "$(DESTDIR)$(gaminincludedir)" || $(MKDIR_P) "$(DESTDIR)$(gaminincludedir)" |
|
@list='$(gamininclude_HEADERS)'; for p in $$list; do \ |
|
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ |
|
f=$(am__strip_dir) \ |
|
@@ -477,7 +477,7 @@ |
|
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) |
|
installdirs: |
|
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gaminincludedir)"; do \ |
|
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \ |
|
+ test -d "$$dir" || $(MKDIR_P) "$$dir"; \ |
|
done |
|
install: install-am |
|
install-exec: install-exec-am |
|
Index: libgamin/gam_api.c |
|
--- libgamin/gam_api.c.orig 2007-08-27 12:21:03.000000000 +0200 |
|
+++ libgamin/gam_api.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -14,6 +14,7 @@ |
|
#include <sys/socket.h> |
|
#include <sys/un.h> |
|
#include <sys/uio.h> |
|
+#include <string.h> |
|
#include "fam.h" |
|
#include "gam_protocol.h" |
|
#include "gam_data.h" |
|
@@ -428,10 +429,10 @@ |
|
{ |
|
char data[2] = { 0, 0 }; |
|
int written; |
|
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) |
|
- struct { |
|
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) |
|
+ union { |
|
struct cmsghdr hdr; |
|
- struct cmsgcred cred; |
|
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; |
|
} cmsg; |
|
struct iovec iov; |
|
struct msghdr msg; |
|
@@ -443,16 +444,16 @@ |
|
msg.msg_iov = &iov; |
|
msg.msg_iovlen = 1; |
|
|
|
- msg.msg_control = &cmsg; |
|
- msg.msg_controllen = sizeof (cmsg); |
|
+ msg.msg_control = (caddr_t) &cmsg; |
|
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); |
|
memset (&cmsg, 0, sizeof (cmsg)); |
|
- cmsg.hdr.cmsg_len = sizeof (cmsg); |
|
+ cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); |
|
cmsg.hdr.cmsg_level = SOL_SOCKET; |
|
cmsg.hdr.cmsg_type = SCM_CREDS; |
|
#endif |
|
|
|
retry: |
|
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) |
|
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) |
|
written = sendmsg(fd, &msg, 0); |
|
#else |
|
written = write(fd, &data[0], 1); |
|
@@ -654,15 +655,16 @@ |
|
gid_t c_gid; |
|
|
|
#ifdef HAVE_CMSGCRED |
|
- struct { |
|
+ struct cmsgcred *cred; |
|
+ union { |
|
struct cmsghdr hdr; |
|
- struct cmsgcred cred; |
|
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; |
|
} cmsg; |
|
#endif |
|
|
|
s_uid = getuid(); |
|
|
|
-#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) |
|
+#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__) |
|
/* Set the socket to receive credentials on the next message */ |
|
{ |
|
int on = 1; |
|
@@ -683,8 +685,8 @@ |
|
|
|
#ifdef HAVE_CMSGCRED |
|
memset(&cmsg, 0, sizeof(cmsg)); |
|
- msg.msg_control = &cmsg; |
|
- msg.msg_controllen = sizeof(cmsg); |
|
+ msg.msg_control = (caddr_t) &cmsg; |
|
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); |
|
#endif |
|
|
|
retry: |
|
@@ -701,7 +703,7 @@ |
|
goto failed; |
|
} |
|
#ifdef HAVE_CMSGCRED |
|
- if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) { |
|
+ if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) || cmsg.hdr.cmsg_type != SCM_CREDS) { |
|
GAM_DEBUG(DEBUG_INFO, |
|
"Message from recvmsg() was not SCM_CREDS\n"); |
|
goto failed; |
|
@@ -727,9 +729,10 @@ |
|
goto failed; |
|
} |
|
#elif defined(HAVE_CMSGCRED) |
|
- c_pid = cmsg.cred.cmcred_pid; |
|
- c_uid = cmsg.cred.cmcred_euid; |
|
- c_gid = cmsg.cred.cmcred_groups[0]; |
|
+ cred = (struct cmsgcred *) CMSG_DATA (&cmsg); |
|
+ c_pid = cred->cmcred_pid; |
|
+ c_uid = cred->cmcred_euid; |
|
+ c_gid = cred->cmcred_groups[0]; |
|
#else /* !SO_PEERCRED && !HAVE_CMSGCRED */ |
|
GAM_DEBUG(DEBUG_INFO, |
|
"Socket credentials not supported on this OS\n"); |
|
@@ -1288,14 +1291,17 @@ |
|
|
|
// FIXME: drop and reacquire lock while blocked? |
|
gamin_data_lock(conn); |
|
- if (!gamin_data_event_ready(conn)) { |
|
+ while ((ret = gamin_data_event_ready(conn)) == 0) { |
|
if (gamin_read_data(conn, fc->fd, 1) < 0) { |
|
gamin_try_reconnect(conn, fc->fd); |
|
FAMErrno = FAM_CONNECT; |
|
return (-1); |
|
} |
|
} |
|
- ret = gamin_data_read_event(conn, fe); |
|
+ |
|
+ if (ret > 0) |
|
+ ret = gamin_data_read_event(conn, fe); |
|
+ |
|
gamin_data_unlock(conn); |
|
|
|
if (ret < 0) { |
|
Index: python/Makefile.in |
|
--- python/Makefile.in.orig 2008-11-24 16:25:07.000000000 +0100 |
|
+++ python/Makefile.in 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -53,7 +53,7 @@ |
|
am__installdirs = "$(DESTDIR)$(pythondir)" "$(DESTDIR)$(pythondir)" |
|
pythonLTLIBRARIES_INSTALL = $(INSTALL) |
|
LTLIBRARIES = $(python_LTLIBRARIES) |
|
-_gamin_la_DEPENDENCIES = $(top_builddir)/libgamin/libgamin-1.la |
|
+_gamin_la_DEPENDENCIES = -lgamin-1 |
|
am__gamin_la_OBJECTS = gamin.lo |
|
_gamin_la_OBJECTS = $(am__gamin_la_OBJECTS) |
|
_gamin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ |
|
@@ -228,7 +228,7 @@ |
|
|
|
python_LTLIBRARIES = _gamin.la |
|
_gamin_la_SOURCES = gamin.c |
|
-_gamin_la_LIBADD = $(top_builddir)/libgamin/libgamin-1.la |
|
+_gamin_la_LIBADD = -lgamin-1 |
|
_gamin_la_LDFLAGS = -module -avoid-version |
|
python_PYTHON = gamin.py |
|
all: all-recursive |
|
Index: server/gam_channel.c |
|
--- server/gam_channel.c.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_channel.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -7,6 +7,7 @@ |
|
#include <sys/stat.h> |
|
#include <sys/un.h> |
|
#include <sys/uio.h> |
|
+#include <string.h> |
|
#include "gam_error.h" |
|
#include "gam_connection.h" |
|
#include "gam_channel.h" |
|
@@ -30,10 +31,10 @@ |
|
{ |
|
char data[2] = { 0, 0 }; |
|
int written; |
|
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) |
|
- struct { |
|
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) |
|
+ union { |
|
struct cmsghdr hdr; |
|
- struct cmsgcred cred; |
|
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; |
|
} cmsg; |
|
struct iovec iov; |
|
struct msghdr msg; |
|
@@ -45,16 +46,16 @@ |
|
msg.msg_iov = &iov; |
|
msg.msg_iovlen = 1; |
|
|
|
- msg.msg_control = &cmsg; |
|
- msg.msg_controllen = sizeof (cmsg); |
|
+ msg.msg_control = (caddr_t) &cmsg; |
|
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); |
|
memset (&cmsg, 0, sizeof (cmsg)); |
|
- cmsg.hdr.cmsg_len = sizeof (cmsg); |
|
+ cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); |
|
cmsg.hdr.cmsg_level = SOL_SOCKET; |
|
cmsg.hdr.cmsg_type = SCM_CREDS; |
|
#endif |
|
|
|
retry: |
|
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) |
|
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) |
|
written = sendmsg(fd, &msg, 0); |
|
#else |
|
written = write(fd, &data[0], 1); |
|
@@ -95,15 +96,16 @@ |
|
gid_t c_gid; |
|
|
|
#ifdef HAVE_CMSGCRED |
|
- struct { |
|
+ struct cmsgcred *cred; |
|
+ union { |
|
struct cmsghdr hdr; |
|
- struct cmsgcred cred; |
|
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; |
|
} cmsg; |
|
#endif |
|
|
|
s_uid = getuid(); |
|
|
|
-#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) |
|
+#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__) |
|
/* Set the socket to receive credentials on the next message */ |
|
{ |
|
int on = 1; |
|
@@ -124,8 +126,8 @@ |
|
|
|
#ifdef HAVE_CMSGCRED |
|
memset(&cmsg, 0, sizeof(cmsg)); |
|
- msg.msg_control = &cmsg; |
|
- msg.msg_controllen = sizeof(cmsg); |
|
+ msg.msg_control = (caddr_t) &cmsg; |
|
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); |
|
#endif |
|
|
|
retry: |
|
@@ -142,7 +144,7 @@ |
|
goto failed; |
|
} |
|
#ifdef HAVE_CMSGCRED |
|
- if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) { |
|
+ if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) || cmsg.hdr.cmsg_type != SCM_CREDS) { |
|
GAM_DEBUG(DEBUG_INFO, |
|
"Message from recvmsg() was not SCM_CREDS\n"); |
|
goto failed; |
|
@@ -168,9 +170,10 @@ |
|
goto failed; |
|
} |
|
#elif defined(HAVE_CMSGCRED) |
|
- c_pid = cmsg.cred.cmcred_pid; |
|
- c_uid = cmsg.cred.cmcred_euid; |
|
- c_gid = cmsg.cred.cmcred_groups[0]; |
|
+ cred = (struct cmsgcred *) CMSG_DATA (&cmsg); |
|
+ c_pid = cred->cmcred_pid; |
|
+ c_uid = cred->cmcred_euid; |
|
+ c_gid = cred->cmcred_groups[0]; |
|
#else /* !SO_PEERCRED && !HAVE_CMSGCRED */ |
|
GAM_DEBUG(DEBUG_INFO, |
|
"Socket credentials not supported on this OS\n"); |
|
@@ -620,6 +623,7 @@ |
|
{ |
|
int fd; |
|
struct sockaddr_un addr; |
|
+ struct stat st; |
|
|
|
fd = socket(PF_UNIX, SOCK_STREAM, 0); |
|
if (fd < 0) { |
|
@@ -640,9 +644,19 @@ |
|
* some extra protection checks. Also make sure the socket is created |
|
* with restricted mode |
|
*/ |
|
- if (!gam_check_secure_path(path)) { |
|
+ if (!gam_check_secure_dir()) { |
|
+ close(fd); |
|
return (-1); |
|
} |
|
+ |
|
+ if (stat(path, &st) == 0) { |
|
+ /* bind() will fail if the socket already exists */ |
|
+ if (unlink(path) < 0) { |
|
+ GAM_DEBUG(DEBUG_INFO, "Failed to remove %s\n", path); |
|
+ close(fd); |
|
+ return (-1); |
|
+ } |
|
+ } |
|
strncpy(&addr.sun_path[0], path, (sizeof(addr) - 4) - 1); |
|
umask(0077); |
|
#endif |
|
Index: server/gam_fs.c |
|
--- server/gam_fs.c.orig 2008-11-12 21:45:28.000000000 +0100 |
|
+++ server/gam_fs.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -7,6 +7,11 @@ |
|
#include <string.h> |
|
#include <errno.h> |
|
#include <glib.h> |
|
+#ifdef __FreeBSD__ |
|
+#include <sys/param.h> |
|
+#include <sys/ucred.h> |
|
+#include <sys/mount.h> |
|
+#endif |
|
#include "gam_error.h" |
|
#include "gam_fs.h" |
|
|
|
@@ -21,9 +26,13 @@ |
|
typedef struct _gam_fs { |
|
char *path; |
|
char *fsname; |
|
+ guint64 flags; |
|
} gam_fs; |
|
|
|
static gboolean initialized = FALSE; |
|
+#ifdef __FreeBSD__ |
|
+static gboolean initializing = FALSE; |
|
+#endif |
|
static GList *filesystems = NULL; |
|
static GList *fs_props = NULL; |
|
static struct stat mtab_sbuf; |
|
@@ -110,6 +119,7 @@ |
|
return strlen(fsb->path) - strlen (fsa->path); |
|
} |
|
|
|
+#ifdef __linux__ |
|
static void |
|
gam_fs_scan_mtab (void) |
|
{ |
|
@@ -165,10 +175,41 @@ |
|
gam_fs_free_filesystems (); |
|
filesystems = g_list_sort (new_filesystems, gam_fs_filesystem_sort_cb); |
|
} |
|
+#endif |
|
+ |
|
+#ifdef __FreeBSD__ |
|
+static void |
|
+gam_fs_getmntinfo (void) |
|
+{ |
|
+ struct statfs *stat; |
|
+ GList *new_filesystems = NULL; |
|
+ gam_fs *fs = NULL; |
|
+ int i, n; |
|
+ |
|
+ n = getmntinfo(&stat, MNT_NOWAIT); |
|
+ if (n == -1) |
|
+ return; |
|
+ |
|
+ for (i = 0; i < n; i++) |
|
+ { |
|
+ fs = g_new0 (gam_fs, 1); |
|
+ fs->path = g_strdup (stat[i].f_mntonname); |
|
+ fs->fsname = g_strdup (stat[i].f_fstypename); |
|
+ fs->flags = stat[i].f_flags; |
|
+ |
|
+ new_filesystems = g_list_prepend (new_filesystems, fs); |
|
+ } |
|
+ |
|
+ /* Replace the old file systems list with the new one */ |
|
+ gam_fs_free_filesystems (); |
|
+ filesystems = g_list_sort (new_filesystems, gam_fs_filesystem_sort_cb); |
|
+} |
|
+#endif |
|
|
|
void |
|
gam_fs_init (void) |
|
{ |
|
+#if defined(__linux__) |
|
if (initialized == FALSE) |
|
{ |
|
initialized = TRUE; |
|
@@ -181,6 +222,7 @@ |
|
if (stat("/etc/mtab", &mtab_sbuf) != 0) |
|
{ |
|
GAM_DEBUG(DEBUG_INFO, "Could not stat /etc/mtab\n"); |
|
+ return; |
|
} |
|
gam_fs_scan_mtab (); |
|
} else { |
|
@@ -189,6 +231,7 @@ |
|
if (stat("/etc/mtab", &sbuf) != 0) |
|
{ |
|
GAM_DEBUG(DEBUG_INFO, "Could not stat /etc/mtab\n"); |
|
+ return; |
|
} |
|
|
|
/* /etc/mtab has changed */ |
|
@@ -199,6 +242,54 @@ |
|
|
|
mtab_sbuf = sbuf; |
|
} |
|
+#elif defined(__FreeBSD__) |
|
+ if (initialized == FALSE && initializing == FALSE) |
|
+ { |
|
+ GList *iterator = NULL; |
|
+ GHashTable *fs_hash = NULL; |
|
+ gam_fs *fs = NULL; |
|
+ |
|
+ initialized = TRUE; |
|
+ initializing = TRUE; |
|
+ |
|
+ gam_fs_getmntinfo (); |
|
+ |
|
+ iterator = filesystems; |
|
+ fs_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); |
|
+ |
|
+ while (iterator) { |
|
+ fs = iterator->data; |
|
+ |
|
+ if (!g_hash_table_lookup (fs_hash, fs->fsname)) { |
|
+ if (fs->flags & MNT_LOCAL) |
|
+ gam_fs_set (fs->fsname, GFS_MT_DEFAULT, 0); |
|
+ else |
|
+ gam_fs_set (fs->fsname, GFS_MT_POLL, 5); |
|
+ |
|
+ g_hash_table_insert (fs_hash, g_strdup (fs->fsname), GINT_TO_POINTER (1)); |
|
+ } |
|
+ |
|
+ iterator = g_list_next (iterator); |
|
+ } |
|
+ |
|
+ g_hash_table_destroy (fs_hash); |
|
+ initializing = FALSE; |
|
+ } else if (initializing == FALSE) { |
|
+ struct stat sbuf; |
|
+ |
|
+ if (stat ("/etc/fstab", &sbuf) != 0) { |
|
+ GAM_DEBUG(DEBUG_INFO, "Could not stat /etc/fstab\n"); |
|
+ return; |
|
+ } |
|
+ |
|
+ if (sbuf.st_mtime != mtab_sbuf.st_mtime) { |
|
+ GAM_DEBUG(DEBUG_INFO, "Updating list of mounted filesystems\n"); |
|
+ gam_fs_getmntinfo (); |
|
+ } |
|
+ |
|
+ mtab_sbuf = sbuf; |
|
+ } |
|
+#endif |
|
} |
|
|
|
gam_fs_mon_type |
|
@@ -210,7 +301,11 @@ |
|
props = gam_fs_find_fs_props (path); |
|
|
|
if (!props) |
|
+#ifdef USE_GAMIN_POLLER |
|
+ return GFS_MT_POLL; |
|
+#else |
|
return GFS_MT_DEFAULT; |
|
+#endif |
|
|
|
return props->mon_type; |
|
} |
|
Index: server/gam_kqueue.c |
|
--- server/gam_kqueue.c.orig 2007-07-04 15:50:41.000000000 +0200 |
|
+++ server/gam_kqueue.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -5,7 +5,8 @@ |
|
* |
|
* * http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650&db=bks&fname=/SGI_Developer/books/IIDsktp_IG/sgi_html/ch08.html |
|
* states that FAM does not follow monitored symbolic links: we |
|
- * do the same (note that regarding |
|
+ * do NOT do the same to preserve compatibility with SGI FAM (note |
|
+ * that regarding |
|
* http://oss.sgi.com/bugzilla/show_bug.cgi?id=405, we do what |
|
* FAM should do: we do not call g_dir_open() if the file is a |
|
* symbolic link). |
|
@@ -28,10 +29,9 @@ |
|
* - kqueue needs to be augmented with a filename-based |
|
* monitoring facility; |
|
* |
|
- * - kqueue needs to be moved out the UFS code. |
|
- * |
|
* Copyright (C) 2005 Joe Marcus Clarke <marcus@FreeBSD.org> |
|
- * Copyright (C) 2005 Jean-Yves Lefort <jylefort@FreeBSD.org> |
|
+ * Copyright (C) 2005, 2006 Jean-Yves Lefort <jylefort@FreeBSD.org> |
|
+ * Copyright (C) 2006 Alex Dupre <ale@FreeBSD.org> |
|
* |
|
* This library is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU Lesser General Public |
|
@@ -53,6 +53,9 @@ |
|
#include <fcntl.h> |
|
#include <unistd.h> |
|
#include <sys/param.h> |
|
+#ifndef USE_GAMIN_POLLER |
|
+#include <sys/mount.h> |
|
+#endif |
|
#include <sys/types.h> |
|
#include <sys/sysctl.h> |
|
#include <sys/stat.h> |
|
@@ -62,6 +65,7 @@ |
|
#include "gam_error.h" |
|
#include "gam_kqueue.h" |
|
#include "gam_event.h" |
|
+#include "gam_excludes.h" |
|
#include "gam_server.h" |
|
#include "gam_poll_basic.h" |
|
|
|
@@ -130,7 +134,7 @@ |
|
HashTableRemoveFunc remove; |
|
HashTablePostRemoveFunc post_remove; |
|
} HashTableMethods; |
|
- |
|
+ |
|
/* |
|
* A hash table which can be modified while iterating over it. |
|
*/ |
|
@@ -281,8 +285,8 @@ |
|
gam_kqueue_mini_lstat (const char *pathname, MiniStat *mini_sb) |
|
{ |
|
struct stat sb; |
|
- |
|
- if (lstat(pathname, &sb) < 0) |
|
+ |
|
+ if (stat(pathname, &sb) < 0) |
|
memset(mini_sb, 0, sizeof(*mini_sb)); |
|
else |
|
{ |
|
@@ -319,14 +323,14 @@ |
|
else |
|
{ |
|
struct stat sb; |
|
- return lstat(pathname, &sb) >= 0 && (sb.st_mode & S_IFDIR) != 0; |
|
+ return stat(pathname, &sb) >= 0 && (sb.st_mode & S_IFDIR) != 0; |
|
} |
|
} |
|
|
|
static gboolean |
|
gam_kqueue_get_uint_sysctl (const char *name, unsigned int *value) |
|
{ |
|
- unsigned int value_len = sizeof(*value); |
|
+ size_t value_len = sizeof(*value); |
|
|
|
if (sysctlbyname(name, value, &value_len, (void *)NULL, 0) < 0) |
|
{ |
|
@@ -406,7 +410,7 @@ |
|
table->iterating = TRUE; |
|
g_hash_table_foreach(table->main, func, user_data); |
|
table->iterating = FALSE; |
|
- |
|
+ |
|
if (table->pending_additions) |
|
{ |
|
GSList *l; |
|
@@ -509,33 +513,52 @@ |
|
gam_kqueue_monitor_enable_kqueue (Monitor *mon) |
|
{ |
|
struct kevent ev[1]; |
|
+#ifndef USE_GAMIN_POLLER |
|
+ struct statfs sb; |
|
+#endif |
|
|
|
if (open_files == max_open_files) |
|
{ |
|
GAM_DEBUG(DEBUG_INFO, "cannot open %s (max_open_files limit reached), falling back to poll\n", mon->pathname); |
|
return FALSE; |
|
} |
|
- |
|
- mon->fd = open(mon->pathname, O_RDONLY | O_NOFOLLOW); |
|
+ |
|
+ if (gam_exclude_check(mon->pathname)) |
|
+ { |
|
+ GAM_DEBUG(DEBUG_INFO, "not using kqueue for %s since it is excluded, falling back to poll\n", mon->pathname); |
|
+ return FALSE; |
|
+ } |
|
+ |
|
+ mon->fd = open(mon->pathname, O_RDONLY | O_NONBLOCK | O_NOFOLLOW); |
|
if (mon->fd < 0) |
|
{ |
|
GAM_DEBUG(DEBUG_INFO, "cannot open %s (%s), falling back to poll\n", mon->pathname, g_strerror(errno)); |
|
return FALSE; |
|
} |
|
|
|
+#ifndef USE_GAMIN_POLLER |
|
+ if (fstatfs(mon->fd, &sb) == 0 && (sb.f_flags & MNT_LOCAL) == 0) |
|
+ { |
|
+ GAM_DEBUG(DEBUG_INFO, "%s resides on a remote file system, falling back to poll\n", mon->pathname); |
|
+ goto poll; |
|
+ } |
|
+#endif |
|
+ |
|
EV_SET(ev, mon->fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, VN_NOTE_ALL, 0, mon); |
|
if (kevent(kq, ev, G_N_ELEMENTS(ev), NULL, 0, NULL) < 0) |
|
{ |
|
GAM_DEBUG(DEBUG_INFO, "cannot enable kqueue notification for %s (%s), falling back to poll\n", mon->pathname, g_strerror(errno)); |
|
- |
|
- close(mon->fd); |
|
- mon->fd = -1; |
|
- |
|
- return FALSE; |
|
+ goto poll; |
|
} |
|
|
|
open_files++; |
|
return TRUE; |
|
+ |
|
+ poll: |
|
+ close(mon->fd); |
|
+ mon->fd = -1; |
|
+ |
|
+ return FALSE; |
|
} |
|
|
|
static void |
|
@@ -612,7 +635,7 @@ |
|
gam_kqueue_poller_remove_sub_monitor(&missing_smon_poller, smon); |
|
gam_kqueue_poller_remove_sub_monitor(&unsupported_smon_poller, smon); |
|
/* unsupported_dirs_poller is handled by _clear_fmons() below */ |
|
- |
|
+ |
|
gam_kqueue_sub_monitor_clear_fmons(smon); |
|
gam_kqueue_monitor_free(MONITOR(smon)); |
|
} |
|
@@ -700,7 +723,7 @@ |
|
{ |
|
struct stat sb; |
|
|
|
- exists = lstat(mon->pathname, &sb) >= 0; |
|
+ exists = stat(mon->pathname, &sb) >= 0; |
|
flags |= (exists && (sb.st_mode & S_IFDIR) != 0) ? MONITOR_ISDIR : MONITOR_ISNOTDIR; |
|
} |
|
|
|
@@ -715,21 +738,21 @@ |
|
{ |
|
GDir *dir; |
|
GError *err = NULL; |
|
- |
|
+ |
|
dir = g_dir_open(mon->pathname, 0, &err); |
|
if (dir) |
|
{ |
|
const char *filename; |
|
- |
|
+ |
|
while ((filename = g_dir_read_name(dir))) |
|
{ |
|
FileMonitor *fmon; |
|
FileMonitorFlags fmon_flags; |
|
- |
|
+ |
|
fmon = gam_kqueue_file_monitor_new(smon, filename, &fmon_flags); |
|
gam_kqueue_file_monitor_emit_event(fmon, gevent, fmon_flags); |
|
} |
|
- |
|
+ |
|
g_dir_close(dir); |
|
} |
|
else |
|
@@ -749,7 +772,7 @@ |
|
|
|
return; |
|
} |
|
- |
|
+ |
|
/* then we enable kqueue notification, falling back to poll if necessary */ |
|
|
|
if (! gam_kqueue_monitor_enable_kqueue(mon)) |
|
@@ -774,7 +797,7 @@ |
|
|
|
filenames = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
|
|
|
- if (isdir) /* do not follow symbolic links */ |
|
+ if (isdir) |
|
{ |
|
GDir *dir; |
|
GError *err = NULL; |
|
@@ -783,7 +806,7 @@ |
|
if (dir) |
|
{ |
|
const char *filename; |
|
- |
|
+ |
|
while ((filename = g_dir_read_name(dir))) |
|
{ |
|
g_hash_table_insert(filenames, g_strdup(filename), GINT_TO_POINTER(TRUE)); |
|
@@ -793,12 +816,12 @@ |
|
{ |
|
FileMonitor *fmon; |
|
FileMonitorFlags fmon_flags; |
|
- |
|
+ |
|
fmon = gam_kqueue_file_monitor_new(smon, filename, &fmon_flags); |
|
gam_kqueue_file_monitor_emit_event(fmon, GAMIN_EVENT_CREATED, fmon_flags); |
|
} |
|
} |
|
- |
|
+ |
|
g_dir_close(dir); |
|
} |
|
else |
|
@@ -840,6 +863,8 @@ |
|
case GAMIN_EVENT_MOVED: |
|
gam_kqueue_sub_monitor_set_missing(smon); |
|
break; |
|
+ default: |
|
+ break; |
|
} |
|
|
|
gam_server_emit_event(mon->pathname, isdir, event, smon->subs, 1); |
|
@@ -931,11 +956,11 @@ |
|
gboolean isdir; |
|
gboolean stat_done; |
|
gboolean stat_succeeded; |
|
- |
|
+ |
|
if ((flags & MONITOR_ISDIR) == 0 && (flags & MONITOR_ISNOTDIR) == 0) |
|
{ |
|
stat_done = TRUE; |
|
- stat_succeeded = lstat(mon->pathname, &sb) >= 0; |
|
+ stat_succeeded = stat(mon->pathname, &sb) >= 0; |
|
isdir = stat_succeeded && (sb.st_mode & S_IFDIR) != 0; |
|
} |
|
else |
|
@@ -943,7 +968,7 @@ |
|
stat_done = FALSE; |
|
isdir = (flags & MONITOR_ISDIR) != 0; |
|
} |
|
- |
|
+ |
|
gam_server_emit_event(mon->pathname, isdir, event, fmon->smon->subs, 1); |
|
|
|
switch (event) |
|
@@ -962,7 +987,7 @@ |
|
{ |
|
FileMonitor *new_fmon; |
|
FileMonitorFlags new_fmon_flags; |
|
- |
|
+ |
|
/* |
|
* The file exists again. It means that kqueue has |
|
* aggregated a removal+creation into a single event. We |
|
@@ -978,9 +1003,11 @@ |
|
break; /* do not remove the fmon we've just created */ |
|
} |
|
} |
|
- |
|
+ |
|
gam_kqueue_hash_table_remove(fmon->smon->fmons, fmon); |
|
break; |
|
+ default: |
|
+ break; |
|
} |
|
} |
|
|
|
@@ -1033,7 +1060,7 @@ |
|
|
|
for (i = 0; i < nevents; i++) |
|
MONITOR(ev[i].udata)->handle_kevent(MONITOR(ev[i].udata), &ev[i]); |
|
- |
|
+ |
|
return TRUE; /* keep source */ |
|
} |
|
|
|
@@ -1042,7 +1069,7 @@ |
|
{ |
|
struct stat sb; |
|
|
|
- if (lstat(MONITOR(smon)->pathname, &sb) >= 0) |
|
+ if (stat(MONITOR(smon)->pathname, &sb) >= 0) |
|
{ |
|
gam_kqueue_poller_remove_sub_monitor(&missing_smon_poller, smon); |
|
gam_kqueue_sub_monitor_enable_notification(smon, SUB_MONITOR_WAS_MISSING | ((sb.st_mode & S_IFDIR) != 0 ? MONITOR_ISDIR : MONITOR_ISNOTDIR)); |
|
@@ -1062,16 +1089,16 @@ |
|
if (gam_kqueue_monitor_enable_kqueue(mon)) |
|
gam_kqueue_poller_remove_sub_monitor(&missing_smon_poller, smon); |
|
} |
|
- |
|
+ |
|
gam_kqueue_mini_lstat(mon->pathname, &sb); |
|
- |
|
+ |
|
if (! sb.exists && mon->sb.exists) |
|
event = GAMIN_EVENT_DELETED; |
|
else if (gam_kqueue_differs(&sb, &mon->sb)) |
|
event = GAMIN_EVENT_CHANGED; |
|
else |
|
return; |
|
- |
|
+ |
|
memcpy(&mon->sb, &sb, sizeof(sb)); |
|
gam_kqueue_sub_monitor_emit_event(smon, event, (sb.mode & S_IFDIR) != 0 ? MONITOR_ISDIR : MONITOR_ISNOTDIR); |
|
} |
|
@@ -1167,7 +1194,10 @@ |
|
channel = g_io_channel_unix_new(kq); |
|
g_io_add_watch(channel, G_IO_IN, gam_kqueue_kevent_cb, NULL); |
|
|
|
- |
|
+#ifdef USE_GAMIN_POLLER |
|
+ gam_poll_basic_init (); |
|
+#endif |
|
+ |
|
gam_server_install_kernel_hooks(GAMIN_K_KQUEUE, |
|
gam_kqueue_add_subscription, |
|
gam_kqueue_remove_subscription, |
|
@@ -1200,7 +1230,7 @@ |
|
smon->subs = g_list_append(smon->subs, sub); |
|
return TRUE; |
|
} |
|
- |
|
+ |
|
smon = gam_kqueue_sub_monitor_new(sub); |
|
smon->subs = g_list_append(smon->subs, sub); |
|
|
|
@@ -1260,6 +1290,6 @@ |
|
success = FALSE; |
|
|
|
g_list_free(subs); |
|
- |
|
+ |
|
return success; |
|
} |
|
Index: server/gam_node.c |
|
--- server/gam_node.c.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_node.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -23,6 +23,7 @@ |
|
#include "gam_event.h" |
|
#include "gam_node.h" |
|
#include "gam_error.h" |
|
+#include "gam_server.h" |
|
|
|
/** |
|
* Create a new node |
|
@@ -122,7 +123,7 @@ |
|
* it has finished with the string. If it must keep it longer, it |
|
* should makes its own copy. The returned string must not be freed. |
|
*/ |
|
-G_CONST_RETURN char * |
|
+const char * |
|
gam_node_get_path(GamNode * node) |
|
{ |
|
g_assert(node); |
|
Index: server/gam_node.h |
|
--- server/gam_node.h.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_node.h 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -58,7 +58,7 @@ |
|
void gam_node_set_is_dir (GamNode *node, |
|
gboolean is_dir); |
|
|
|
-G_CONST_RETURN char *gam_node_get_path (GamNode *node); |
|
+const char *gam_node_get_path (GamNode *node); |
|
|
|
GList *gam_node_get_subscriptions (GamNode *node); |
|
|
|
Index: server/gam_poll_basic.c |
|
--- server/gam_poll_basic.c.orig 2007-07-04 15:46:29.000000000 +0200 |
|
+++ server/gam_poll_basic.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -345,7 +345,7 @@ |
|
#ifdef ST_MTIM_NSEC |
|
GAM_DEBUG(DEBUG_INFO, "%d %d : %d %d\n", node->sbuf.st_mtim.tv_sec, node->sbuf.st_mtim.tv_nsec, sbuf.st_mtim.tv_sec, sbuf.st_mtim.tv_nsec); |
|
#else |
|
- GAM_DEBUG(DEBUG_INFO, "%d : %d\n", node->sbuf.st_mtime, sbuf.st_mtim.tv_nsec); |
|
+ GAM_DEBUG(DEBUG_INFO, "%d : %d\n", node->sbuf.st_mtime, sbuf.st_mtime); |
|
#endif /* ST_MTIM_NSEC */ |
|
#endif /* VERBOSE_POLL */ |
|
} |
|
Index: server/gam_server.c |
|
--- server/gam_server.c.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_server.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -32,7 +32,7 @@ |
|
#include "gam_server.h" |
|
#include "gam_channel.h" |
|
#include "gam_subscription.h" |
|
-#include "gam_poll_generic.h" |
|
+#include "gam_poll_basic.h" |
|
#ifdef ENABLE_INOTIFY |
|
#include "gam_inotify.h" |
|
#endif |
|
@@ -200,7 +200,8 @@ |
|
return gam_poll_add_subscription (sub); |
|
else |
|
#endif |
|
- return gam_kernel_add_subscription (sub); |
|
+ /*return gam_kernel_add_subscription (sub);*/ |
|
+ return gam_poll_add_subscription (sub); |
|
} else { |
|
gam_fs_mon_type type; |
|
type = gam_fs_get_mon_type (path); |
|
@@ -243,7 +244,8 @@ |
|
return gam_poll_remove_subscription (sub); |
|
else |
|
#endif |
|
- return gam_kernel_remove_subscription(sub); |
|
+ /*return gam_kernel_remove_subscription(sub);*/ |
|
+ return gam_poll_remove_subscription (sub); |
|
} else { |
|
gam_fs_mon_type type; |
|
type = gam_fs_get_mon_type (path); |
|
@@ -438,7 +440,7 @@ |
|
GamPollHandler |
|
gam_server_get_poll_handler (void) |
|
{ |
|
- return __gam_kernel_handler; |
|
+ return __gam_poll_handler; |
|
} |
|
|
|
gboolean |
|
Index: server/gam_subscription.c |
|
--- server/gam_subscription.c.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_subscription.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -141,7 +141,7 @@ |
|
* @param sub the GamSubscription |
|
* @returns The path being monitored. It should not be freed. |
|
*/ |
|
-G_CONST_RETURN char * |
|
+const char * |
|
gam_subscription_get_path(GamSubscription * sub) |
|
{ |
|
if (sub == NULL) |
|
Index: server/gam_subscription.h |
|
--- server/gam_subscription.h.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ server/gam_subscription.h 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -21,7 +21,7 @@ |
|
|
|
int gam_subscription_get_reqno (GamSubscription *sub); |
|
|
|
-G_CONST_RETURN char *gam_subscription_get_path (GamSubscription *sub); |
|
+const char *gam_subscription_get_path (GamSubscription *sub); |
|
|
|
GamListener *gam_subscription_get_listener (GamSubscription *sub); |
|
|
|
Index: tests/testing.c |
|
--- tests/testing.c.orig 2007-07-04 15:36:49.000000000 +0200 |
|
+++ tests/testing.c 2012-07-25 13:58:16.000000000 +0200 |
|
@@ -376,11 +376,11 @@ |
|
} |
|
printf("chmod %s to %s\n", arg, arg2); |
|
} else if (!strcmp(command, "chown")) { |
|
+ struct stat sb; |
|
if (args != 3) { |
|
fprintf(stderr, "chown line %d: lacks path and owner\n", no); |
|
return (-1); |
|
} |
|
- struct stat sb; |
|
if (!lstat (arg, &sb)) { |
|
ret = (S_ISLNK (sb.st_mode)) ? |
|
lchown(arg, strtol(arg2, NULL, 10), -1) : |
|
@@ -486,9 +486,9 @@ |
|
return (-1); |
|
} |
|
/* |
|
- * wait at most 3 secs before declaring failure |
|
+ * wait at most 7 secs before declaring failure |
|
*/ |
|
- while ((delay < 30) && (testState.nb_events < nb_events + count)) { |
|
+ while ((delay < 70) && (testState.nb_events < nb_events + count)) { |
|
debugLoop(100); |
|
|
|
/* printf("+"); fflush(stdout); */
|
|
|