From 7ea4b245e9e21e94a25c858388080bde6bc273e9 Mon Sep 17 00:00:00 2001 From: Martin Schlemmer Date: Tue, 2 Aug 2005 20:52:53 +0000 Subject: Update version. (Portage version: 2.0.51.22-r2) --- app-admin/gamin/files/digest-gamin-0.1.3 | 1 + app-admin/gamin/files/gamin-0.1.3-freebsd.patch | 100 +++ .../files/gamin-0.1.3-inotify-legacy-backend.patch | 884 +++++++++++++++++++++ 3 files changed, 985 insertions(+) create mode 100644 app-admin/gamin/files/digest-gamin-0.1.3 create mode 100644 app-admin/gamin/files/gamin-0.1.3-freebsd.patch create mode 100644 app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch (limited to 'app-admin/gamin/files') diff --git a/app-admin/gamin/files/digest-gamin-0.1.3 b/app-admin/gamin/files/digest-gamin-0.1.3 new file mode 100644 index 000000000000..c631ea112523 --- /dev/null +++ b/app-admin/gamin/files/digest-gamin-0.1.3 @@ -0,0 +1 @@ +MD5 1670da322c89ad56e778d36e7fb7c9e9 gamin-0.1.3.tar.gz 518087 diff --git a/app-admin/gamin/files/gamin-0.1.3-freebsd.patch b/app-admin/gamin/files/gamin-0.1.3-freebsd.patch new file mode 100644 index 000000000000..d732c7f3e4b8 --- /dev/null +++ b/app-admin/gamin/files/gamin-0.1.3-freebsd.patch @@ -0,0 +1,100 @@ +diff -ur -x '*~' gamin-0.1.2/libgamin/gam_api.c gamin-0.1.2-fbsd/libgamin/gam_api.c +--- gamin-0.1.2/libgamin/gam_api.c 2005-06-15 12:53:25.000000000 +0200 ++++ gamin-0.1.2-fbsd/libgamin/gam_api.c 2005-07-16 00:15:37.317345328 +0200 +@@ -421,7 +421,7 @@ + { + char data[2] = { 0, 0 }; + int written; +-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) + struct { + struct cmsghdr hdr; + struct cmsgcred cred; +@@ -445,7 +445,7 @@ + #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); +@@ -655,7 +655,7 @@ + + 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; +Only in gamin-0.1.2-fbsd/libgamin: gam_api.c.orig +diff -ur -x '*~' gamin-0.1.2/libgamin/gam_data.c gamin-0.1.2-fbsd/libgamin/gam_data.c +--- gamin-0.1.2/libgamin/gam_data.c 2005-05-18 16:45:04.000000000 +0200 ++++ gamin-0.1.2-fbsd/libgamin/gam_data.c 2005-07-16 12:06:58.586806112 +0200 +@@ -17,6 +17,10 @@ + #ifdef HAVE_PTHREAD_H + #include + ++# ifdef __GLIBC__ ++# define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP ++# endif ++ + static int is_threaded = -1; + #endif + +@@ -471,7 +475,7 @@ + } + if (is_threaded > 0) { + pthread_mutexattr_init(&attr); +- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); ++ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&ret->lock, &attr); + pthread_mutexattr_destroy(&attr); + } +diff -ur -x '*~' gamin-0.1.2/server/gam_channel.c gamin-0.1.2-fbsd/server/gam_channel.c +--- gamin-0.1.2/server/gam_channel.c 2005-06-15 13:02:34.000000000 +0200 ++++ gamin-0.1.2-fbsd/server/gam_channel.c 2005-07-16 00:15:37.326343960 +0200 +@@ -29,7 +29,7 @@ + { + char data[2] = { 0, 0 }; + int written; +-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__)) + struct { + struct cmsghdr hdr; + struct cmsgcred cred; +@@ -53,7 +53,7 @@ + #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); +@@ -100,7 +100,7 @@ + + 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; +diff -ur -x '*~' gamin-0.1.2/tests/testing.c gamin-0.1.2-fbsd/tests/testing.c +--- gamin-0.1.2/tests/testing.c 2005-06-13 10:59:29.000000000 +0200 ++++ gamin-0.1.2-fbsd/tests/testing.c 2005-07-16 00:15:37.337342288 +0200 +@@ -436,9 +436,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); */ +Only in gamin-0.1.2-fbsd/tests: testing.c.orig diff --git a/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch b/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch new file mode 100644 index 000000000000..c551a01e0dc6 --- /dev/null +++ b/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch @@ -0,0 +1,884 @@ +Add support for INotify Legacy backend (pre 0.24) + +diff -urpN gamin-0.1.2/configure.in gamin-0.1.2.az/configure.in +--- gamin-0.1.2/configure.in 2005-07-13 13:10:43.000000000 +0200 ++++ gamin-0.1.2.az/configure.in 2005-07-16 09:23:22.000000000 +0200 +@@ -225,16 +225,41 @@ dnl check if inotify backend is enabled + AM_CONDITIONAL(ENABLE_INOTIFY, test x$inotify = xtrue) + + if test x$inotify = xtrue; then +- AC_CHECK_HEADERS(linux/inotify.h) ++ AC_CHECK_HEADERS(linux/inotify.h, ++ [AC_CHECK_DECL(INOTIFY_IOCTL_MAGIC, ++ [AC_DEFINE(HAVE_INOTIFY_IOCTL_MAGIC,1,[Have legacy linux/inotify.h])], ++ [],[#include ])]) + AC_DEFINE(ENABLE_INOTIFY,1,[Use inotify as backend]) + backends="${backends}, inotify" + fi + ++if test x$os = xlinux-gnu; then ++ AC_ARG_ENABLE(inotify-legacy, ++ [ --enable-inotify-legacy Enable the INotify Legacy backend], ++ [case "${enableval}" in ++ yes) inotify_legacy=true ;; ++ no) inotify_legacy=false;; ++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-inotify-legacy) ;; ++ esac],[inotify_legacy=false]) ++fi ++ ++dnl check if inotify legacy backend is enabled ++AM_CONDITIONAL(ENABLE_INOTIFY_LEGACY, test x$inotify_legacy = xtrue) ++ ++if test x$inotify_legacy = xtrue; then ++ AC_CHECK_HEADERS(linux/inotify.h, ++ [AC_CHECK_DECL(INOTIFY_IOCTL_MAGIC, ++ [AC_DEFINE(HAVE_INOTIFY_IOCTL_MAGIC,1,[Have legacy linux/inotify.h])], ++ [],[#include ])]) ++ AC_DEFINE(ENABLE_INOTIFY_LEGACY,1,[Use inotify legacy as backend]) ++ backends="${backends}, inotify_legacy" ++fi ++ + if test x$os != xBogusOS; then + AC_CHECK_FUNC(kevent,[have_kevent=1],) + if test x$have_kevent = x1 ; then + AC_ARG_ENABLE(kqueue, +- [ --disable-kqueue Disable the KQueue backend], ++ [ --disable-kqueue Disable the KQueue backend], + [case "${enableval}" in + yes) kqueue=true ;; + no) kqueue=false ;; +diff -urpN gamin-0.1.2/server/Makefile.am gamin-0.1.2.az/server/Makefile.am +--- gamin-0.1.2/server/Makefile.am 2005-06-08 23:48:00.000000000 +0200 ++++ gamin-0.1.2.az/server/Makefile.am 2005-07-16 09:26:06.000000000 +0200 +@@ -41,6 +41,7 @@ gam_server_SOURCES = \ + gam_excludes.h \ + local_inotify.h \ + local_inotify_syscalls.h \ ++ local_inotify_legacy.h \ + gam_fs.c \ + gam_fs.h \ + server_config.h +@@ -49,6 +50,10 @@ if ENABLE_INOTIFY + gam_server_SOURCES += gam_inotify.c gam_inotify.h + endif + ++if ENABLE_INOTIFY_LEGACY ++gam_server_SOURCES += gam_inotify_legacy.c gam_inotify_legacy.h ++endif ++ + if ENABLE_DNOTIFY + gam_server_SOURCES += gam_dnotify.c gam_dnotify.h + endif +diff -urpN gamin-0.1.2/server/gam_inotify.c gamin-0.1.2.az/server/gam_inotify.c +--- gamin-0.1.2/server/gam_inotify.c 2005-07-12 23:15:19.000000000 +0200 ++++ gamin-0.1.2.az/server/gam_inotify.c 2005-07-16 09:24:31.000000000 +0200 +@@ -32,7 +32,7 @@ + #include + #include "gam_error.h" + #include "gam_poll.h" +-#ifdef HAVE_LINUX_INOTIFY_H ++#if defined(HAVE_LINUX_INOTIFY_H) && !defined(HAVE_INOTIFY_IOCTL_MAGIC) + #include + #else + #include "local_inotify.h" +diff -urpN gamin-0.1.2/server/gam_inotify_legacy.c gamin-0.1.2.az/server/gam_inotify_legacy.c +--- gamin-0.1.2/server/gam_inotify_legacy.c 1970-01-01 02:00:00.000000000 +0200 ++++ gamin-0.1.2.az/server/gam_inotify_legacy.c 2005-07-16 09:36:47.000000000 +0200 +@@ -0,0 +1,611 @@ ++/* gamin inotify_legacy backend ++ * Copyright (C) 2005 John McCutchan ++ * ++ * Based off of code, ++ * Copyright (C) 2003 James Willcox, Corey Bowers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free ++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++ ++#include "server_config.h" ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include "gam_error.h" ++#include "gam_poll.h" ++#if defined(HAVE_LINUX_INOTIFY_H) && defined(HAVE_INOTIFY_IOCTL_MAGIC) ++#include ++#else ++#include "local_inotify_legacy.h" ++#endif ++#include "gam_inotify_legacy.h" ++#include "gam_tree.h" ++#include "gam_event.h" ++#include "gam_server.h" ++#include "gam_event.h" ++#ifdef GAMIN_DEBUG_API ++#include "gam_debugging.h" ++#endif ++ ++typedef struct { ++ char *path; ++ int wd; ++ int refcount; ++ GList *subs; ++ int busy; ++ gboolean deactivated; ++ int events; ++ int deactivated_events; ++} inotify_legacy_data_t; ++ ++static GHashTable *path_hash = NULL; ++static GHashTable *wd_hash = NULL; ++ ++G_LOCK_DEFINE_STATIC(inotify_legacy); ++ ++static GIOChannel *inotify_legacy_read_ioc = NULL; ++ ++static gboolean have_consume_idler = FALSE; ++ ++static int inotify_legacy_device_fd = -1; ++ ++static guint should_poll_mask = IN_MODIFY|IN_ATTRIB|IN_CLOSE_WRITE|IN_MOVED_FROM|IN_MOVED_TO|IN_DELETE|IN_CREATE|IN_DELETE_SELF|IN_UNMOUNT; ++ ++static void ++gam_inotify_legacy_data_debug (gpointer key, gpointer value, gpointer user_data) ++{ ++ inotify_legacy_data_t *data = (inotify_legacy_data_t *)value; ++ ++ if (!data) ++ return; ++ ++ int deactivated = data->deactivated; ++ ++ GAM_DEBUG(DEBUG_INFO, "isub wd %d refs %d busy %d deactivated %d events (%d:%d): %s\n", data->wd, data->refcount, data->busy, deactivated, data->events, data->deactivated_events, data->path); ++} ++ ++void ++gam_inotify_legacy_debug(void) ++{ ++ if (inotify_legacy_device_fd == -1) ++ { ++ GAM_DEBUG(DEBUG_INFO, "Inotify device not opened\n"); ++ return; ++ } ++ ++ if (path_hash == NULL) ++ return; ++ ++ GAM_DEBUG(DEBUG_INFO, "Inotify device fd = %d\n", inotify_legacy_device_fd); ++ GAM_DEBUG(DEBUG_INFO, "Dumping inotify_legacy subscriptions\n"); ++ g_hash_table_foreach (path_hash, gam_inotify_legacy_data_debug, NULL); ++} ++ ++static void print_mask(int mask) ++{ ++ if (mask & IN_ACCESS) ++ { ++ GAM_DEBUG(DEBUG_INFO, "ACCESS\n"); ++ } ++ if (mask & IN_MODIFY) ++ { ++ GAM_DEBUG(DEBUG_INFO, "MODIFY\n"); ++ } ++ if (mask & IN_ATTRIB) ++ { ++ GAM_DEBUG(DEBUG_INFO, "ATTRIB\n"); ++ } ++ if (mask & IN_CLOSE_WRITE) ++ { ++ GAM_DEBUG(DEBUG_INFO, "CLOSE_WRITE\n"); ++ } ++ if (mask & IN_CLOSE_NOWRITE) ++ { ++ GAM_DEBUG(DEBUG_INFO, "CLOSE_WRITE\n"); ++ } ++ if (mask & IN_OPEN) ++ { ++ GAM_DEBUG(DEBUG_INFO, "OPEN\n"); ++ } ++ if (mask & IN_MOVED_FROM) ++ { ++ GAM_DEBUG(DEBUG_INFO, "MOVE_FROM\n"); ++ } ++ if (mask & IN_MOVED_TO) ++ { ++ GAM_DEBUG(DEBUG_INFO, "MOVE_TO\n"); ++ } ++ if (mask & IN_DELETE) ++ { ++ GAM_DEBUG(DEBUG_INFO, "DELETE\n"); ++ } ++ if (mask & IN_CREATE) ++ { ++ GAM_DEBUG(DEBUG_INFO, "CREATE_SUBDIR\n"); ++ } ++ if (mask & IN_DELETE_SELF) ++ { ++ GAM_DEBUG(DEBUG_INFO, "DELETE_SELF\n"); ++ } ++ if (mask & IN_UNMOUNT) ++ { ++ GAM_DEBUG(DEBUG_INFO, "UNMOUNT\n"); ++ } ++ if (mask & IN_Q_OVERFLOW) ++ { ++ GAM_DEBUG(DEBUG_INFO, "Q_OVERFLOW\n"); ++ } ++ if (mask & IN_IGNORED) ++ { ++ GAM_DEBUG(DEBUG_INFO, "IGNORED\n"); ++ } ++} ++ ++static inotify_legacy_data_t * ++gam_inotify_legacy_data_new(const char *path, int wd) ++{ ++ inotify_legacy_data_t *data; ++ ++ data = g_new0(inotify_legacy_data_t, 1); ++ data->path = g_strdup(path); ++ data->wd = wd; ++ data->busy = 0; ++ data->refcount = 1; ++ data->deactivated_events = 0; ++ data->events = 0; ++ ++ return data; ++} ++ ++static void ++gam_inotify_legacy_data_free(inotify_legacy_data_t * data) ++{ ++ if (data->refcount != 0) ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_data_free called with reffed data.\n"); ++ g_free(data->path); ++ g_free(data); ++} ++ ++static void ++gam_inotify_legacy_directory_handler_internal(const char *path, pollHandlerMode mode) ++{ ++ inotify_legacy_data_t *data; ++ int path_fd, path_wd; ++ struct inotify_watch_request iwr; ++ switch (mode) { ++ case GAMIN_ACTIVATE: ++ GAM_DEBUG(DEBUG_INFO, "Adding %s to inotify_legacy\n", path); ++ break; ++ case GAMIN_DESACTIVATE: ++ GAM_DEBUG(DEBUG_INFO, "Removing %s from inotify_legacy\n", path); ++ break; ++ case GAMIN_FLOWCONTROLSTART: ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: Start flow control for %s\n", path); ++ break; ++ case GAMIN_FLOWCONTROLSTOP: ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: Stop flow control for %s\n", path); ++ break; ++ default: ++ gam_error(DEBUG_INFO, "Unknown inotify_legacy operation %d for %s\n", ++ mode, path); ++ return; ++ } ++ ++ G_LOCK(inotify_legacy); ++ ++ if (mode == GAMIN_ACTIVATE) { ++ ++ if ((data = g_hash_table_lookup(path_hash, path)) != NULL) { ++ data->refcount++; ++ GAM_DEBUG(DEBUG_INFO, " found incremented refcount: %d\n", ++ data->refcount); ++ G_UNLOCK(inotify_legacy); ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyChange, path, data->refcount); ++#endif ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy updated refcount\n"); ++ return; ++ } ++ ++ path_fd = open(path, O_RDONLY); ++ ++ if (path_fd < 0) { ++ G_UNLOCK(inotify_legacy); ++ return; ++ } ++ ++ iwr.fd = path_fd; ++ iwr.mask = should_poll_mask; ++ path_wd = ioctl (inotify_legacy_device_fd, INOTIFY_WATCH, &iwr); ++ close (path_fd); ++ ++ data = gam_inotify_legacy_data_new(path, path_wd); ++ g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), data); ++ g_hash_table_insert(path_hash, data->path, data); ++ ++ GAM_DEBUG(DEBUG_INFO, "activated inotify_legacy for %s\n", path); ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyCreate, path, 0); ++#endif ++ } else if (mode == GAMIN_DESACTIVATE) { ++ data = g_hash_table_lookup(path_hash, path); ++ ++ if (!data) { ++ GAM_DEBUG(DEBUG_INFO, " not found !!!\n"); ++ ++ G_UNLOCK(inotify_legacy); ++ return; ++ } ++ ++ data->refcount--; ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy decremeneted refcount for %s\n", ++ path); ++ ++ if (data->refcount == 0) { ++ int wd = data->wd; ++ GAM_DEBUG(DEBUG_INFO, "removed inotify_legacy watch for %s\n", ++ data->path); ++ g_hash_table_remove(path_hash, data->path); ++ g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd)); ++ gam_inotify_legacy_data_free(data); ++ if (ioctl (inotify_legacy_device_fd, INOTIFY_IGNORE, &wd) < 0) { ++ GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd); ++ } ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyDelete, data->path, 0); ++#endif ++ } else { ++ GAM_DEBUG(DEBUG_INFO, " found decremented refcount: %d\n", ++ data->refcount); ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyChange, data->path, data->refcount); ++#endif ++ } ++ } else if ((mode == GAMIN_FLOWCONTROLSTART) || ++ (mode == GAMIN_FLOWCONTROLSTOP)) { ++ data = g_hash_table_lookup(path_hash, path); ++ if (!data) { ++ GAM_DEBUG(DEBUG_INFO, " not found !!!\n"); ++ ++ G_UNLOCK(inotify_legacy); ++ return; ++ } ++ if (data != NULL) { ++ if (mode == GAMIN_FLOWCONTROLSTART) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: GAMIN_FLOWCONTROLSTART for %s\n", data->path); ++ if (data->wd >= 0) { ++ if (ioctl (inotify_legacy_device_fd, INOTIFY_IGNORE, &data->wd) < 0) { ++ GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd); ++ } ++ data->deactivated = TRUE; ++ GAM_DEBUG(DEBUG_INFO, "deactivated inotify_legacy for %s\n", ++ data->path); ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyFlowOn, data->path, 0); ++#endif ++ } ++ data->busy++; ++ } else { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: GAMIN_FLOWCONTROLSTOP for %s\n", data->path); ++ if (data->busy > 0) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: data->busy > 0 for %s\n", data->path); ++ data->busy--; ++ if (data->busy == 0) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: data->busy == 0 for %s\n", data->path); ++ path_fd = open(data->path, O_RDONLY); ++ if (path_fd < 0) { ++ G_UNLOCK(inotify_legacy); ++ GAM_DEBUG(DEBUG_INFO, ++ "failed to reactivate inotify_legacy for %s\n", ++ data->path); ++ ++ return; ++ } ++ ++ iwr.fd = path_fd; ++ iwr.mask = should_poll_mask; ++ path_wd = ioctl (inotify_legacy_device_fd, INOTIFY_WATCH, &iwr); ++ close (path_fd); ++ ++ /* Remove the old wd from the hash table */ ++ g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd)); ++ ++ data->wd = path_wd; ++ data->deactivated = FALSE; ++ ++ /* Insert the new wd into the hash table */ ++ g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), ++ data); ++ GAM_DEBUG(DEBUG_INFO, "reactivated inotify_legacy for %s\n", ++ data->path); ++#ifdef GAMIN_DEBUG_API ++ gam_debug_report(GAMinotifyFlowOff, path, 0); ++#endif ++ } ++ } ++ } ++ } ++ } else { ++ GAM_DEBUG(DEBUG_INFO, "Unimplemented operation\n"); ++ } ++ ++ G_UNLOCK(inotify_legacy); ++} ++ ++static void ++gam_inotify_legacy_directory_handler(const char *path, pollHandlerMode mode) ++{ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_directory_handler %s : %d\n", ++ path, mode); ++ ++ gam_inotify_legacy_directory_handler_internal(path, mode); ++} ++ ++static void ++gam_inotify_legacy_file_handler(const char *path, pollHandlerMode mode) ++{ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_file_handler %s : %d\n", path, mode); ++ ++ if (g_file_test(path, G_FILE_TEST_IS_DIR)) { ++ gam_inotify_legacy_directory_handler_internal(path, mode); ++ } else { ++ GAM_DEBUG(DEBUG_INFO, " not a dir %s, FAILED!!!\n", path); ++ } ++} ++ ++static void ++gam_inotify_legacy_q_overflow (gpointer key, gpointer value, gpointer user_data) ++{ ++ inotify_legacy_data_t *data = (inotify_legacy_data_t *)value; ++ ++ gam_poll_scan_directory (data->path); ++} ++ ++static gboolean ++gam_inotify_legacy_read_handler(gpointer user_data) ++{ ++ char *buffer; ++ int buffer_size; ++ int events; ++ gsize buffer_i, read_size; ++ ++ G_LOCK(inotify_legacy); ++ ++ if (ioctl(inotify_legacy_device_fd, FIONREAD, &buffer_size) < 0) { ++ G_UNLOCK(inotify_legacy); ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy FIONREAD < 0. kaboom!\n"); ++ return FALSE; ++ } ++ ++ buffer = g_malloc(buffer_size); ++ ++ if (g_io_channel_read_chars(inotify_legacy_read_ioc, (char *)buffer, buffer_size, &read_size, NULL) != G_IO_STATUS_NORMAL) { ++ G_UNLOCK(inotify_legacy); ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy failed to read events from inotify_legacy fd.\n"); ++ g_free (buffer); ++ return FALSE; ++ } ++ ++ buffer_i = 0; ++ events = 0; ++ while (buffer_i < read_size) { ++ struct inotify_event *event; ++ gsize event_size; ++ inotify_legacy_data_t *data; ++ ++ event = (struct inotify_event *)&buffer[buffer_i]; ++ event_size = sizeof(struct inotify_event) + event->len; ++ ++ data = g_hash_table_lookup (wd_hash, GINT_TO_POINTER(event->wd)); ++ if (!data) { ++ GAM_DEBUG(DEBUG_INFO, "processing event: inotify_legacy can't find wd %d\n", event->wd); ++ } else if (data->deactivated) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: ignoring event on temporarily deactivated watch %s\n", data->path); ++ data->deactivated_events++; ++ } else { ++ if (event->mask == IN_IGNORED) { ++ GList *l; ++ ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: IN_IGNORE on wd=%d\n", event->wd); ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: removing all subscriptions for %s\n", data->path); ++ ++ data->events++; ++ ++ l = data->subs; ++ data->subs = NULL; ++ for (l = l; l; l = l->next) { ++ GamSubscription *sub = l->data; ++ gam_inotify_legacy_remove_subscription (sub); ++ } ++ } else if (event->mask != IN_Q_OVERFLOW) { ++ if (event->mask & should_poll_mask) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy requesting poll for %s\n", data->path); ++ GAM_DEBUG(DEBUG_INFO, "poll was requested for event = "); ++ print_mask (event->mask); ++ data->events++; ++ gam_poll_scan_directory (data->path); ++ } ++ } else if (event->mask == IN_Q_OVERFLOW) { ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy queue over flowed, requesting poll on all watched paths\n"); ++ g_hash_table_foreach (path_hash, gam_inotify_legacy_q_overflow, NULL); ++ } ++ } ++ ++ buffer_i += event_size; ++ events++; ++ } ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy recieved %d events\n", events); ++ ++ g_free(buffer); ++ G_UNLOCK(inotify_legacy); ++ ++ return TRUE; ++} ++ ++ ++static gboolean ++gam_inotify_legacy_consume_subscriptions_real(gpointer data) ++{ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_consume_subscriptions_real()\n"); ++ gam_poll_consume_subscriptions(); ++ have_consume_idler = FALSE; ++ return FALSE; ++} ++ ++static void ++gam_inotify_legacy_consume_subscriptions(void) ++{ ++ GSource *source; ++ ++ if (have_consume_idler) ++ return; ++ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_consume_subscriptions()\n"); ++ have_consume_idler = TRUE; ++ source = g_idle_source_new(); ++ g_source_set_callback(source, gam_inotify_legacy_consume_subscriptions_real, ++ NULL, NULL); ++ g_source_attach(source, NULL); ++} ++ ++/** ++ * @defgroup inotify_legacy inotify_legacy Backend ++ * @ingroup Backends ++ * @brief inotify_legacy backend API ++ * ++ * Since version 2.6.X, Linux kernels have included the Linux Inode ++ * Notification system (inotify_legacy). This backend uses inotify_legacy to know when ++ * files are changed/created/deleted. Since inotify_legacy can't watch files/dirs that ++ * don't exist we still have to cache stat() information. For this, ++ * we can just use the code in the polling backend. ++ * ++ * @{ ++ */ ++ ++ ++/** ++ * Initializes the inotify_legacy backend. This must be called before ++ * any other functions in this module. ++ * ++ * @returns TRUE if initialization succeeded, FALSE otherwise ++ */ ++gboolean ++gam_inotify_legacy_init(void) ++{ ++ GSource *source; ++ ++ g_return_val_if_fail(gam_poll_init_full(FALSE), FALSE); ++ ++ inotify_legacy_device_fd = open("/dev/inotify", O_RDONLY); ++ ++ if (inotify_legacy_device_fd < 0) { ++ GAM_DEBUG(DEBUG_INFO, "Could not open /dev/inotify\n"); ++ return FALSE; ++ } ++ ++ inotify_legacy_read_ioc = g_io_channel_unix_new(inotify_legacy_device_fd); ++ ++ /* For binary data */ ++ g_io_channel_set_encoding(inotify_legacy_read_ioc, NULL, NULL); ++ /* Non blocking */ ++ g_io_channel_set_flags(inotify_legacy_read_ioc, G_IO_FLAG_NONBLOCK, NULL); ++ ++ source = g_io_create_watch(inotify_legacy_read_ioc, ++ G_IO_IN | G_IO_HUP | G_IO_ERR); ++ g_source_set_callback(source, gam_inotify_legacy_read_handler, NULL, NULL); ++ ++ g_source_attach(source, NULL); ++ ++ path_hash = g_hash_table_new(g_str_hash, g_str_equal); ++ wd_hash = g_hash_table_new(g_direct_hash, g_direct_equal); ++ gam_poll_set_kernel_handler(gam_inotify_legacy_directory_handler, ++ gam_inotify_legacy_file_handler, ++ GAMIN_K_INOTIFY); ++ ++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy initialized\n"); ++ ++ gam_backend_add_subscription = gam_inotify_legacy_add_subscription; ++ gam_backend_remove_subscription = gam_inotify_legacy_remove_subscription; ++ gam_backend_remove_all_for = gam_inotify_legacy_remove_all_for; ++ ++ return TRUE; ++} ++ ++/** ++ * Adds a subscription to be monitored. ++ * ++ * @param sub a #GamSubscription to be polled ++ * @returns TRUE if adding the subscription succeeded, FALSE otherwise ++ */ ++gboolean ++gam_inotify_legacy_add_subscription(GamSubscription * sub) ++{ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_add_subscription\n"); ++ ++ if (!gam_poll_add_subscription(sub)) { ++ return FALSE; ++ } ++ ++ gam_inotify_legacy_consume_subscriptions(); ++ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_add_subscription: done\n"); ++ return TRUE; ++} ++ ++/** ++ * Removes a subscription which was being monitored. ++ * ++ * @param sub a #GamSubscription to remove ++ * @returns TRUE if removing the subscription succeeded, FALSE otherwise ++ */ ++gboolean ++gam_inotify_legacy_remove_subscription(GamSubscription * sub) ++{ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_remove_subscription\n"); ++ ++ if (!gam_poll_remove_subscription(sub)) { ++ return FALSE; ++ } ++ ++ gam_inotify_legacy_consume_subscriptions(); ++ ++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_remove_subscription: done\n"); ++ return TRUE; ++} ++ ++/** ++ * Stop monitoring all subscriptions for a given listener. ++ * ++ * @param listener a #GamListener ++ * @returns TRUE if removing the subscriptions succeeded, FALSE otherwise ++ */ ++gboolean ++gam_inotify_legacy_remove_all_for(GamListener * listener) ++{ ++ if (!gam_poll_remove_all_for(listener)) { ++ return FALSE; ++ } ++ ++ gam_inotify_legacy_consume_subscriptions(); ++ ++ return TRUE; ++} ++ ++/** @} */ +diff -urpN gamin-0.1.2/server/gam_inotify_legacy.h gamin-0.1.2.az/server/gam_inotify_legacy.h +--- gamin-0.1.2/server/gam_inotify_legacy.h 1970-01-01 02:00:00.000000000 +0200 ++++ gamin-0.1.2.az/server/gam_inotify_legacy.h 2005-07-16 08:41:34.000000000 +0200 +@@ -0,0 +1,18 @@ ++#ifndef __GAM_INOTIFY_LEGACY_H__ ++#define __GAM_INOTIFY_LEGACY_H__ ++ ++#include ++#include "gam_poll.h" ++#include "gam_subscription.h" ++ ++G_BEGIN_DECLS ++ ++gboolean gam_inotify_legacy_init (void); ++gboolean gam_inotify_legacy_add_subscription (GamSubscription *sub); ++gboolean gam_inotify_legacy_remove_subscription (GamSubscription *sub); ++gboolean gam_inotify_legacy_remove_all_for (GamListener *listener); ++void gam_inotify_legacy_debug (void); ++ ++G_END_DECLS ++ ++#endif /* __GAM_INOTIFY_LEGACY_H__ */ +diff -urpN gamin-0.1.2/server/gam_server.c gamin-0.1.2.az/server/gam_server.c +--- gamin-0.1.2/server/gam_server.c 2005-06-15 13:02:34.000000000 +0200 ++++ gamin-0.1.2.az/server/gam_server.c 2005-07-16 08:44:19.000000000 +0200 +@@ -36,6 +36,9 @@ + #ifdef ENABLE_INOTIFY + #include "gam_inotify.h" + #endif ++#ifdef ENABLE_INOTIFY_LEGACY ++#include "gam_inotify_legacy.h" ++#endif + #ifdef ENABLE_DNOTIFY + #include "gam_dnotify.h" + #endif +@@ -87,6 +90,9 @@ gam_show_debug(void) { + #ifdef ENABLE_INOTIFY + gam_inotify_debug (); + #endif ++#ifdef ENABLE_INOTIFY_LEGACY ++ gam_inotify_legacy_debug (); ++#endif + #ifdef ENABLE_DNOTIFY + gam_dnotify_debug (); + #endif +@@ -112,6 +118,12 @@ gam_init_subscriptions(void) + return(TRUE); + } + #endif ++#ifdef ENABLE_INOTIFY_LEGACY ++ if (gam_inotify_legacy_init()) { ++ GAM_DEBUG(DEBUG_INFO, "Using INotify Legacy as backend\n"); ++ return(TRUE); ++ } ++#endif + #ifdef ENABLE_DNOTIFY + if (gam_dnotify_init()) { + GAM_DEBUG(DEBUG_INFO, "Using DNotify as backend\n"); +diff -urpN gamin-0.1.2/server/local_inotify_legacy.h gamin-0.1.2.az/server/local_inotify_legacy.h +--- gamin-0.1.2/server/local_inotify_legacy.h 1970-01-01 02:00:00.000000000 +0200 ++++ gamin-0.1.2.az/server/local_inotify_legacy.h 2005-07-16 08:42:16.000000000 +0200 +@@ -0,0 +1,124 @@ ++/* ++ * Inode based directory notification for Linux ++ * ++ * Copyright (C) 2005 John McCutchan ++ */ ++ ++#ifndef _LINUX_INOTIFY_LEGACY_H ++#define _LINUX_INOTIFY_LEGACY_H ++ ++#include ++ ++/* ++ * struct inotify_event - structure read from the inotify device for each event ++ * ++ * When you are watching a directory, you will receive the filename for events ++ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd. ++ */ ++struct inotify_event { ++ __s32 wd; /* watch descriptor */ ++ __u32 mask; /* watch mask */ ++ __u32 cookie; /* cookie to synchronize two events */ ++ __u32 len; /* length (including nulls) of name */ ++ char name[0]; /* stub for possible name */ ++}; ++ ++/* ++ * struct inotify_watch_request - represents a watch request ++ * ++ * Pass to the inotify device via the INOTIFY_WATCH ioctl ++ */ ++struct inotify_watch_request { ++ int fd; /* fd of filename to watch */ ++ __u32 mask; /* event mask */ ++}; ++ ++/* the following are legal, implemented events that user-space can watch for */ ++#define IN_ACCESS 0x00000001 /* File was accessed */ ++#define IN_MODIFY 0x00000002 /* File was modified */ ++#define IN_ATTRIB 0x00000004 /* Metadata changed */ ++#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ ++#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ ++#define IN_OPEN 0x00000020 /* File was opened */ ++#define IN_MOVED_FROM 0x00000040 /* File was moved from X */ ++#define IN_MOVED_TO 0x00000080 /* File was moved to Y */ ++#define IN_CREATE 0x00000100 /* Subfile was created */ ++#define IN_DELETE 0x00000200 /* Subfile was deleted */ ++#define IN_DELETE_SELF 0x00000400 /* Self was deleted */ ++ ++/* the following are legal events. they are sent as needed to any watch */ ++#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ ++#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ ++#define IN_IGNORED 0x00008000 /* File was ignored */ ++ ++/* helper events */ ++#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */ ++#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ ++ ++/* special flags */ ++#define IN_ISDIR 0x40000000 /* event occurred against dir */ ++#define IN_ONESHOT 0x80000000 /* only send event once */ ++ ++/* ++ * All of the events - we build the list by hand so that we can add flags in ++ * the future and not break backward compatibility. Apps will get only the ++ * events that they originally wanted. Be sure to add new events here! ++ */ ++#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \ ++ IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \ ++ IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF) ++ ++#define INOTIFY_IOCTL_MAGIC 'Q' ++#define INOTIFY_IOCTL_MAXNR 2 ++ ++#define INOTIFY_WATCH _IOR(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch_request) ++#define INOTIFY_IGNORE _IOR(INOTIFY_IOCTL_MAGIC, 2, int) ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++#ifdef CONFIG_INOTIFY ++ ++extern void inotify_inode_queue_event(struct inode *, __u32, __u32, ++ const char *); ++extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32, ++ const char *); ++extern void inotify_unmount_inodes(struct list_head *); ++extern void inotify_inode_is_dead(struct inode *); ++extern u32 inotify_get_cookie(void); ++ ++#else ++ ++static inline void inotify_inode_queue_event(struct inode *inode, ++ __u32 mask, __u32 cookie, ++ const char *filename) ++{ ++} ++ ++static inline void inotify_dentry_parent_queue_event(struct dentry *dentry, ++ __u32 mask, __u32 cookie, ++ const char *filename) ++{ ++} ++ ++static inline void inotify_unmount_inodes(struct list_head *list) ++{ ++} ++ ++static inline void inotify_inode_is_dead(struct inode *inode) ++{ ++} ++ ++static inline u32 inotify_get_cookie(void) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_INOTIFY */ ++ ++#endif /* __KERNEL __ */ ++ ++#endif /* _LINUX_INOTIFY_LEGACY_H */ -- cgit v1.2.3-65-gdbad