diff --git a/devel/Makefile b/devel/Makefile index a19ce01e3d7b..3ad51c1b372b 100644 --- a/devel/Makefile +++ b/devel/Makefile @@ -271,6 +271,7 @@ SUBDIR += g-wrap SUBDIR += g2c SUBDIR += gaa + SUBDIR += gamin SUBDIR += gaphor SUBDIR += gauche-gaunit SUBDIR += gauche-readline diff --git a/devel/gamin/Makefile b/devel/gamin/Makefile new file mode 100644 index 000000000000..1bf34abb76b0 --- /dev/null +++ b/devel/gamin/Makefile @@ -0,0 +1,45 @@ +# ports collection makefile for: gamin +# Date created: 24 March 2005 +# Whom: Joe Marcus Clarke +# +# $FreeBSD$ +# + +PORTNAME= gamin +PORTVERSION= 0.0.26 +PORTREVISION?= 8 +CATEGORIES?= devel +MASTER_SITES= http://www.gnome.org/~veillard/gamin/sources/ + +MAINTAINER?= gnome@FreeBSD.org +COMMENT?= A file and directory monitoring system + +USE_GMAKE= yes +USE_LIBTOOL_VER=15 +USE_GNOME?= gnomehack glib20 +INSTALLS_SHLIB= yes +CONFIGURE_ARGS?=--disable-gtk-doc --with-html-dir=${PREFIX}/share/doc \ + --without-python +CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \ + LDFLAGS="-L${LOCALBASE}/lib" + +CONFLICTS= fam-[0-9]* + +.if !defined(GAMIN_SLAVE) +OPTIONS= KQUEUE "Enable the KQueue backend (UFS only)" on +.endif + +.include + +.if !defined(GAMIN_SLAVE) +.if defined(WITHOUT_KQUEUE) +CONFIGURE_ARGS+= --disable-kqueue +.else +CONFIGURE_ARGS+= --enable-kqueue +.endif +.endif + +post-patch: + @${FIND} ${WRKSRC} -type f | ${XARGS} ${TOUCH} -f + +.include diff --git a/devel/gamin/distinfo b/devel/gamin/distinfo new file mode 100644 index 000000000000..498f60829967 --- /dev/null +++ b/devel/gamin/distinfo @@ -0,0 +1,2 @@ +MD5 (gamin-0.0.26.tar.gz) = 3d716b6533466f9ca69df13c58009981 +SIZE (gamin-0.0.26.tar.gz) = 484070 diff --git a/devel/gamin/files/patch-config.h.in b/devel/gamin/files/patch-config.h.in new file mode 100644 index 000000000000..095ee06375ee --- /dev/null +++ b/devel/gamin/files/patch-config.h.in @@ -0,0 +1,12 @@ +--- config.h.in.orig Thu Mar 24 23:41:54 2005 ++++ config.h.in Thu Mar 24 23:42:12 2005 +@@ -6,6 +6,9 @@ + /* Use inotify as backend */ + #undef ENABLE_INOTIFY + ++/* Use kqueue as backend */ ++#undef ENABLE_KQUEUE ++ + /* Use polling as backend */ + #undef ENABLE_POLLING + diff --git a/devel/gamin/files/patch-configure b/devel/gamin/files/patch-configure new file mode 100644 index 000000000000..c26ef854cf2e --- /dev/null +++ b/devel/gamin/files/patch-configure @@ -0,0 +1,76 @@ +--- configure.orig Fri Mar 25 01:48:07 2005 ++++ configure Fri Mar 25 02:17:01 2005 +@@ -463,7 +463,7 @@ + # include + #endif" + +-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os GAMIN_MAJOR_VERSION GAMIN_MINOR_VERSION GAMIN_MICRO_VERSION GAMIN_VERSION GAMIN_VERSION_INFO FAM_VERSION_INFO INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL RELDATE HTML_DIR ENABLE_GTK_DOC_TRUE ENABLE_GTK_DOC_FALSE PKG_CONFIG DAEMON_CFLAGS DAEMON_LIBS LIBGAMIN_CFLAGS LIBGAMIN_LIBS TEST_CFLAGS TEST_LIBS GAMIN_DEBUG_TRUE GAMIN_DEBUG_FALSE BUILD_DOCS_TRUE BUILD_DOCS_FALSE HAVE_LINUX_TRUE HAVE_LINUX_FALSE ENABLE_DNOTIFY_TRUE ENABLE_DNOTIFY_FALSE ENABLE_INOTIFY_TRUE ENABLE_INOTIFY_FALSE PYTHON WITH_PYTHON_TRUE WITH_PYTHON_FALSE pythondir PYTHON_VERSION PYTHON_SUBDIR PYTHON_INCLUDES PYTHON_PYTHON_SITE_PACKAGES LIBOBJS LTLIBOBJS' ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os GAMIN_MAJOR_VERSION GAMIN_MINOR_VERSION GAMIN_MICRO_VERSION GAMIN_VERSION GAMIN_VERSION_INFO FAM_VERSION_INFO INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL RELDATE HTML_DIR ENABLE_GTK_DOC_TRUE ENABLE_GTK_DOC_FALSE PKG_CONFIG DAEMON_CFLAGS DAEMON_LIBS LIBGAMIN_CFLAGS LIBGAMIN_LIBS TEST_CFLAGS TEST_LIBS GAMIN_DEBUG_TRUE GAMIN_DEBUG_FALSE BUILD_DOCS_TRUE BUILD_DOCS_FALSE HAVE_LINUX_TRUE HAVE_LINUX_FALSE ENABLE_DNOTIFY_TRUE ENABLE_DNOTIFY_FALSE ENABLE_KQUEUE_TRUE ENABLE_KQUEUE_FALSE ENABLE_INOTIFY_TRUE ENABLE_INOTIFY_FALSE PYTHON WITH_PYTHON_TRUE WITH_PYTHON_FALSE pythondir PYTHON_VERSION PYTHON_SUBDIR PYTHON_INCLUDES PYTHON_SITE_PACKAGES LIBOBJS LTLIBOBJS' + ac_subst_files='' + + # Initialize some variables set by options. +@@ -21926,7 +21926,7 @@ + + + debug_api=no +-if test "`hostname`" == "paphio" -a "`pwd`" == "/u/veillard/gamin" ++if test "`hostname`" = "paphio" -a "`pwd`" = "/u/veillard/gamin" + then + debug_api=yes + fi +@@ -22051,6 +22051,37 @@ + backends="${backends}, dnotify" + fi + ++if test "${enable_kqueue+set}" = set; then ++ enableval="$enable_kqueue" ++ case "${enableval}" in ++ yes) kqueue=true ;; ++ no) kqueue=false ;; ++ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --disable-kqueue" >&5 ++echo "$as_me: error: bad value ${enableval} for --disable-kqueue" >&2;} ++ { (exit 1); exit 1; }; } ;; ++ esac ++else ++ kqueue=true ++fi ++ ++if test x$kqueue = xtrue; then ++ ENABLE_KQUEUE_TRUE= ++ ENABLE_KQUEUE_FALSE='#' ++else ++ ENABLE_KQUEUE_TRUE='#' ++ ENABLE_KQUEUE_FALSE= ++fi ++ ++ ++if test x$kqueue = xtrue; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define ENABLE_KQUEUE 1 ++_ACEOF ++ ++ backends="${backends}, kqueue" ++fi ++ + if test x$os = xlinux-gnu; then + # Check whether --enable-inotify or --disable-inotify was given. + if test "${enable_inotify+set}" = set; then +@@ -23472,6 +23503,8 @@ + s,@HAVE_LINUX_FALSE@,$HAVE_LINUX_FALSE,;t t + s,@ENABLE_DNOTIFY_TRUE@,$ENABLE_DNOTIFY_TRUE,;t t + s,@ENABLE_DNOTIFY_FALSE@,$ENABLE_DNOTIFY_FALSE,;t t ++s,@ENABLE_KQUEUE_TRUE@,$ENABLE_KQUEUE_TRUE,;t t ++s,@ENABLE_KQUEUE_FALSE@,$ENABLE_KQUEUE_FALSE,;t t + s,@ENABLE_INOTIFY_TRUE@,$ENABLE_INOTIFY_TRUE,;t t + s,@ENABLE_INOTIFY_FALSE@,$ENABLE_INOTIFY_FALSE,;t t + s,@PYTHON@,$PYTHON,;t t +@@ -23481,7 +23514,7 @@ + s,@PYTHON_VERSION@,$PYTHON_VERSION,;t t + s,@PYTHON_SUBDIR@,$PYTHON_SUBDIR,;t t + s,@PYTHON_INCLUDES@,$PYTHON_INCLUDES,;t t +-s,@PYTHON_PYTHON_SITE_PACKAGES@,$PYTHON_PYTHON_SITE_PACKAGES,;t t ++s,@PYTHON_SITE_PACKAGES@,$PYTHON_SITE_PACKAGES,;t t + s,@LIBOBJS@,$LIBOBJS,;t t + s,@LTLIBOBJS@,$LTLIBOBJS,;t t + CEOF diff --git a/devel/gamin/files/patch-configure.in b/devel/gamin/files/patch-configure.in new file mode 100644 index 000000000000..b1e2cdebc85a --- /dev/null +++ b/devel/gamin/files/patch-configure.in @@ -0,0 +1,31 @@ +--- configure.in.orig Wed Mar 30 15:19:06 2005 ++++ configure.in Wed Mar 30 15:38:58 2005 +@@ -230,6 +230,28 @@ + backends="${backends}, inotify" + 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], ++ [case "${enableval}" in ++ yes) kqueue=true ;; ++ no) kqueue=false ;; ++ *) AC_MSG_ERROR(bad value ${enableval} for --disable-kqueue) ;; ++ esac],[kqueue=true]) ++ fi ++fi ++ ++dnl check if kqueue backend is enabled ++AM_CONDITIONAL(ENABLE_KQUEUE, test x$kqueue = xtrue) ++ ++if test x$kqueue = xtrue; then ++ AC_CHECK_HEADERS(sys/event.h) ++ AC_DEFINE(ENABLE_KQUEUE,1,[Use kqueue as backend]) ++ backends="${backends}, kqueue" ++fi ++ + dnl check for flavours of varargs macros (test from GLib) + AC_MSG_CHECKING(for ISO C99 varargs macros in C) + AC_TRY_COMPILE([],[ diff --git a/devel/gamin/files/patch-libgamin_gam_api.c b/devel/gamin/files/patch-libgamin_gam_api.c new file mode 100644 index 000000000000..c5cedfce6801 --- /dev/null +++ b/devel/gamin/files/patch-libgamin_gam_api.c @@ -0,0 +1,98 @@ +--- libgamin/gam_api.c.orig Thu Mar 24 19:07:08 2005 ++++ libgamin/gam_api.c Thu Mar 24 19:26:39 2005 +@@ -181,7 +181,6 @@ gamin_get_socket_dir(void) + snprintf(path, MAXPATHLEN, "/tmp/fam-%s", user); + path[MAXPATHLEN] = 0; + ret = strdup(path); +- free(user); + return (ret); + } + +@@ -421,9 +420,35 @@ gamin_write_credential_byte(int fd) + { + char data[2] = { 0, 0 }; + int written; ++#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++ struct { ++ struct cmsghdr hdr; ++ struct cmsgcred cred; ++ } cmsg; ++ struct iovec iov; ++ struct msghdr msg; ++ ++ iov.iov_base = &data[0]; ++ iov.iov_len = 1; ++ ++ memset (&msg, 0, sizeof (msg)); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ msg.msg_control = &cmsg; ++ msg.msg_controllen = sizeof (cmsg); ++ memset (&cmsg, 0, sizeof (cmsg)); ++ cmsg.hdr.cmsg_len = sizeof (cmsg); ++ cmsg.hdr.cmsg_level = SOL_SOCKET; ++ cmsg.hdr.cmsg_type = SCM_CREDS; ++#endif + + retry: ++#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++ written = sendmsg(fd, &msg, 0); ++#else + written = write(fd, &data[0], 1); ++#endif + if (written < 0) { + if (errno == EINTR) + goto retry; +@@ -616,8 +641,10 @@ gamin_check_cred(GAMDataPtr conn, int fd + gid_t c_gid; + + #ifdef HAVE_CMSGCRED +- char cmsgmem[CMSG_SPACE(sizeof(struct cmsgcred))]; +- struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem; ++ struct { ++ struct cmsghdr hdr; ++ struct cmsgcred cred; ++ } cmsg; + #endif + + s_uid = getuid(); +@@ -642,9 +669,9 @@ gamin_check_cred(GAMDataPtr conn, int fd + msg.msg_iovlen = 1; + + #ifdef HAVE_CMSGCRED +- memset(cmsgmem, 0, sizeof(cmsgmem)); +- msg.msg_control = cmsgmem; +- msg.msg_controllen = sizeof(cmsgmem); ++ memset(&cmsg, 0, sizeof(cmsg)); ++ msg.msg_control = &cmsg; ++ msg.msg_controllen = sizeof(cmsg); + #endif + + retry: +@@ -661,7 +688,7 @@ retry: + goto failed; + } + #ifdef HAVE_CMSGCRED +- if (cmsg->cmsg_len < sizeof(cmsgmem) || cmsg->cmsg_type != SCM_CREDS) { ++ if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) { + GAM_DEBUG(DEBUG_INFO, + "Message from recvmsg() was not SCM_CREDS\n"); + goto failed; +@@ -687,13 +714,9 @@ retry: + goto failed; + } + #elif defined(HAVE_CMSGCRED) +- struct cmsgcred *cred; +- +- cred = (struct cmsgcred *) CMSG_DATA(cmsg); +- +- c_pid = cred->cmcred_pid; +- c_uid = cred->cmcred_euid; +- c_gid = cred->cmcred_groups[0]; ++ c_pid = cmsg.cred.cmcred_pid; ++ c_uid = cmsg.cred.cmcred_euid; ++ c_gid = cmsg.cred.cmcred_groups[0]; + #else /* !SO_PEERCRED && !HAVE_CMSGCRED */ + GAM_DEBUG(DEBUG_INFO, + "Socket credentials not supported on this OS\n"); diff --git a/devel/gamin/files/patch-python_Makefile.in b/devel/gamin/files/patch-python_Makefile.in new file mode 100644 index 000000000000..13580076c7f3 --- /dev/null +++ b/devel/gamin/files/patch-python_Makefile.in @@ -0,0 +1,32 @@ +--- python/Makefile.in.orig Thu Mar 24 19:56:18 2005 ++++ python/Makefile.in Thu Mar 24 19:58:01 2005 +@@ -59,7 +59,7 @@ + pythonLTLIBRARIES_INSTALL = $(INSTALL) + LTLIBRARIES = $(python_LTLIBRARIES) + @WITH_PYTHON_TRUE@am__DEPENDENCIES_1 = \ +-@WITH_PYTHON_TRUE@ $(top_builddir)/libgamin/libgamin-1.la ++@WITH_PYTHON_TRUE@ -lgamin-1 + @WITH_PYTHON_TRUE@_gamin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) + am___gamin_la_SOURCES_DIST = gamin.c + @WITH_PYTHON_TRUE@am__gamin_la_OBJECTS = gamin.lo +@@ -162,7 +162,7 @@ + PKG_CONFIG = @PKG_CONFIG@ + PYTHON = @PYTHON@ + PYTHON_INCLUDES = @PYTHON_INCLUDES@ +-PYTHON_PYTHON_SITE_PACKAGES = @PYTHON_PYTHON_SITE_PACKAGES@ ++PYTHON_SITE_PACKAGES = @PYTHON_SITE_PACKAGES@ + PYTHON_SUBDIR = @PYTHON_SUBDIR@ + PYTHON_VERSION = @PYTHON_VERSION@ + RANLIB = @RANLIB@ +@@ -233,9 +233,9 @@ + gamin.c \ + gamin.py + +-_gamin_la_LDFLAGS = -module -avoid-version -L$(top_builddir)/libgamin/.libs ++_gamin_la_LDFLAGS = -module -avoid-version + @WITH_PYTHON_TRUE@mylibs = \ +-@WITH_PYTHON_TRUE@ $(top_builddir)/libgamin/libgamin-1.la ++@WITH_PYTHON_TRUE@ -lgamin-1 + + @WITH_PYTHON_TRUE@python_LTLIBRARIES = _gamin.la + @WITH_PYTHON_TRUE@_gamin_la_SOURCES = gamin.c diff --git a/devel/gamin/files/patch-server_Makefile.in b/devel/gamin/files/patch-server_Makefile.in new file mode 100644 index 000000000000..233298647382 --- /dev/null +++ b/devel/gamin/files/patch-server_Makefile.in @@ -0,0 +1,47 @@ +--- server/Makefile.in.orig Thu Mar 24 23:04:39 2005 ++++ server/Makefile.in Thu Mar 24 23:07:52 2005 +@@ -43,6 +43,7 @@ + libexec_PROGRAMS = gam_server$(EXEEXT) + @ENABLE_INOTIFY_TRUE@am__append_2 = gam_inotify.c gam_inotify.h + @ENABLE_DNOTIFY_TRUE@am__append_3 = gam_dnotify.c gam_dnotify.h ++@ENABLE_KQUEUE_TRUE@am__append_4 = gam_kqueue.c gam_kqueue.h + subdir = server + DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +@@ -63,15 +64,16 @@ + gam_connection.h gam_debugging.h gam_debugging.c \ + gam_excludes.c gam_excludes.h local_inotify.h \ + gam_debug_lists.c gam_inotify.c gam_inotify.h gam_dnotify.c \ +- gam_dnotify.h ++ gam_dnotify.h gam_kqueue.c gam_kqueue.h + @ENABLE_INOTIFY_TRUE@am__objects_1 = gam_inotify.$(OBJEXT) + @ENABLE_DNOTIFY_TRUE@am__objects_2 = gam_dnotify.$(OBJEXT) ++@ENABLE_KQUEUE_TRUE@am__objects_3 = gam_kqueue.$(OBJEXT) + am_gam_server_OBJECTS = gam_subscription.$(OBJEXT) \ + gam_listener.$(OBJEXT) gam_server.$(OBJEXT) gam_node.$(OBJEXT) \ + gam_tree.$(OBJEXT) gam_poll.$(OBJEXT) gam_channel.$(OBJEXT) \ + gam_connection.$(OBJEXT) gam_debugging.$(OBJEXT) \ + gam_excludes.$(OBJEXT) gam_debug_lists.$(OBJEXT) \ +- $(am__objects_1) $(am__objects_2) ++ $(am__objects_1) $(am__objects_2) $(am__objects_3) + gam_server_OBJECTS = $(am_gam_server_OBJECTS) + am__DEPENDENCIES_1 = + DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +@@ -236,7 +238,8 @@ + gam_poll.h gam_channel.c gam_channel.h gam_connection.c \ + gam_connection.h gam_debugging.h gam_debugging.c \ + gam_excludes.c gam_excludes.h local_inotify.h \ +- gam_debug_lists.c $(am__append_2) $(am__append_3) ++ gam_debug_lists.c $(am__append_2) $(am__append_3) \ ++ $(am__append_4) + gam_server_LDFLAGS = + gam_server_DEPENDENCIES = $(DEPS) + gam_server_LDADD = $(top_builddir)/lib/libgamin_shared.a $(LDADDS) $(LIBGAMIN_LIBS) +@@ -316,6 +319,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_debug_lists.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_debugging.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_dnotify.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_kqueue.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_excludes.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_inotify.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gam_listener.Po@am__quote@ diff --git a/devel/gamin/files/patch-server_gam_channel.c b/devel/gamin/files/patch-server_gam_channel.c new file mode 100644 index 000000000000..7e51df41fd9a --- /dev/null +++ b/devel/gamin/files/patch-server_gam_channel.c @@ -0,0 +1,127 @@ +--- server/gam_channel.c.orig Fri Jan 28 10:54:42 2005 ++++ server/gam_channel.c Sat Mar 26 16:15:55 2005 +@@ -24,11 +24,53 @@ + * to check the server credentials early on. + */ + static gboolean +-gam_client_conn_send_cred(GIOChannel * source, int fd) ++gam_client_conn_send_cred(int fd) + { + char data[2] = { 0, 0 }; ++ int written; ++#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++ struct { ++ struct cmsghdr hdr; ++ struct cmsgcred cred; ++ } cmsg; ++ struct iovec iov; ++ struct msghdr msg; ++ ++ iov.iov_base = &data[0]; ++ iov.iov_len = 1; ++ ++ memset (&msg, 0, sizeof (msg)); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ msg.msg_control = &cmsg; ++ msg.msg_controllen = sizeof (cmsg); ++ memset (&cmsg, 0, sizeof (cmsg)); ++ cmsg.hdr.cmsg_len = sizeof (cmsg); ++ cmsg.hdr.cmsg_level = SOL_SOCKET; ++ cmsg.hdr.cmsg_type = SCM_CREDS; ++#endif + +- return(gam_client_conn_write(source, fd, &data[0], 1)); ++retry: ++#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS) ++ written = sendmsg(fd, &msg, 0); ++#else ++ written = write(fd, &data[0], 1); ++#endif ++ if (written < 0) { ++ if (errno == EINTR) ++ goto retry; ++ gam_error(DEBUG_INFO, ++ "Failed to write credential bytes to socket %d\n", fd); ++ return (-1); ++ } ++ if (written != 1) { ++ gam_error(DEBUG_INFO, "Wrote %d credential bytes to socket %d\n", ++ written, fd); ++ return (-1); ++ } ++ GAM_DEBUG(DEBUG_INFO, "Wrote credential bytes to socket %d\n", fd); ++ return (written); + } + + /** +@@ -49,8 +91,10 @@ gam_client_conn_check_cred(GIOChannel * + gid_t c_gid; + + #ifdef HAVE_CMSGCRED +- char cmsgmem[CMSG_SPACE(sizeof(struct cmsgcred))]; +- struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem; ++ struct { ++ struct cmsghdr hdr; ++ struct cmsgcred cred; ++ } cmsg; + #endif + + s_uid = getuid(); +@@ -75,9 +119,9 @@ gam_client_conn_check_cred(GIOChannel * + msg.msg_iovlen = 1; + + #ifdef HAVE_CMSGCRED +- memset(cmsgmem, 0, sizeof(cmsgmem)); +- msg.msg_control = cmsgmem; +- msg.msg_controllen = sizeof(cmsgmem); ++ memset(&cmsg, 0, sizeof(cmsg)); ++ msg.msg_control = &cmsg; ++ msg.msg_controllen = sizeof(cmsg); + #endif + + retry: +@@ -94,7 +138,7 @@ gam_client_conn_check_cred(GIOChannel * + goto failed; + } + #ifdef HAVE_CMSGCRED +- if (cmsg->cmsg_len < sizeof(cmsgmem) || cmsg->cmsg_type != SCM_CREDS) { ++ if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) { + GAM_DEBUG(DEBUG_INFO, + "Message from recvmsg() was not SCM_CREDS\n"); + goto failed; +@@ -120,13 +164,9 @@ gam_client_conn_check_cred(GIOChannel * + goto failed; + } + #elif defined(HAVE_CMSGCRED) +- struct cmsgcred *cred; +- +- cred = (struct cmsgcred *) CMSG_DATA(cmsg); +- +- c_pid = cred->cmcred_pid; +- c_uid = cred->cmcred_euid; +- c_gid = cred->cmcred_groups[0]; ++ c_pid = cmsg.cred.cmcred_pid; ++ c_uid = cmsg.cred.cmcred_euid; ++ c_gid = cmsg.cred.cmcred_groups[0]; + #else /* !SO_PEERCRED && !HAVE_CMSGCRED */ + GAM_DEBUG(DEBUG_INFO, + "Socket credentials not supported on this OS\n"); +@@ -149,7 +189,7 @@ gam_client_conn_check_cred(GIOChannel * + goto failed; + } + +- if (!gam_client_conn_send_cred(source, fd)) { ++ if (!gam_client_conn_send_cred(fd)) { + GAM_DEBUG(DEBUG_INFO, "Failed to send credential byte to client\n"); + goto failed; + } +@@ -305,6 +345,7 @@ gam_get_socket_path(const char *session) + gam_client_id = g_getenv("GAM_CLIENT_ID"); + if (gam_client_id == NULL) { + GAM_DEBUG(DEBUG_INFO, "Error getting GAM_CLIENT_ID\n"); ++ gam_client_id = ""; + } + } else { + gam_client_id = session; diff --git a/devel/gamin/files/patch-server_gam_kqueue.c b/devel/gamin/files/patch-server_gam_kqueue.c new file mode 100644 index 000000000000..3e5fe770e78d --- /dev/null +++ b/devel/gamin/files/patch-server_gam_kqueue.c @@ -0,0 +1,639 @@ +--- server/gam_kqueue.c.orig Thu Mar 31 20:39:54 2005 ++++ server/gam_kqueue.c Fri Apr 1 01:09:11 2005 +@@ -0,0 +1,636 @@ ++/* ++ * Copyright (C) 2005 Joe Marcus Clarke ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "gam_error.h" ++#include "gam_kqueue.h" ++#include "gam_tree.h" ++#include "gam_event.h" ++#include "gam_server.h" ++#include "gam_event.h" ++ ++typedef struct { ++ char *path; ++ int fd; ++ int refcount; ++ gboolean isdir; ++ GList *subs; ++ GSList *dirlist; ++} KQueueData; ++ ++static GHashTable *dir_path_hash = NULL; ++static GHashTable *file_path_hash = NULL; ++static GHashTable *fd_hash = NULL; ++ ++static GSList *exist_list = NULL; ++ ++static GList *new_subs = NULL; ++G_LOCK_DEFINE_STATIC(new_subs); ++static GList *removed_subs = NULL; ++G_LOCK_DEFINE_STATIC(removed_subs); ++ ++G_LOCK_DEFINE_STATIC(kqueue); ++ ++static gboolean have_consume_idler = FALSE; ++ ++int kq = -1; ++ ++static KQueueData * ++gam_kqueue_data_new(const char *path, int fd) ++{ ++ KQueueData *data; ++ ++ data = g_new0(KQueueData, 1); ++ data->path = g_strdup(path); ++ data->fd = fd; ++ data->refcount = 1; ++ data->isdir = FALSE; ++ data->subs = NULL; ++ data->dirlist = NULL; ++ ++ return data; ++} ++ ++static GSList * ++gam_kqueue_lsdir(const char *path) ++{ ++ GDir *dir; ++ GSList *lst = NULL; ++ const gchar *entry; ++ ++ if (!path) ++ return NULL; ++ ++ dir = g_dir_open(path, 0, NULL); ++ if (!dir) ++ return NULL; ++ ++ entry = g_dir_read_name(dir); ++ ++ while (entry) { ++ lst = g_slist_prepend(lst, g_strdup(entry)); ++ entry = g_dir_read_name(dir); ++ } ++ ++ g_dir_close(dir); ++ ++ return lst; ++} ++ ++static void ++gam_kqueue_cmplst(GSList *lst1, GSList *lst2, GSList **added, GSList **deleted) ++{ ++ int found; ++ GSList *l; ++ ++ if (!lst1 && !lst2) ++ return; ++ ++ if (!lst1) { ++ *added = g_slist_copy(lst2); ++ return; ++ } ++ ++ if (!lst2) { ++ *deleted = g_slist_copy(lst1); ++ return; ++ } ++ ++ for (l = lst1; l; l = l->next) { ++ found = 0; ++ if (g_slist_find_custom(lst2, l->data, (GCompareFunc)strcmp)) { ++ found = 1; ++ } ++ if (found == 0) { ++ *deleted = g_slist_prepend(*deleted, l->data); ++ } ++ } ++ ++ for (l = lst2; l; l = l->next) { ++ found = 0; ++ if (g_slist_find_custom(lst1, l->data, (GCompareFunc)strcmp)) { ++ found = 1; ++ } ++ if (found == 0) { ++ *added = g_slist_prepend(*added, l->data); ++ } ++ } ++} ++ ++static void ++gam_kqueue_data_free(KQueueData * data) ++{ ++ g_free(data->path); ++ if (data->dirlist) { ++ g_slist_foreach(data->dirlist, (GFunc)g_free, NULL); ++ g_slist_free(data->dirlist); ++ } ++ if (data->subs) { ++ g_list_free(data->subs); ++ } ++ g_free(data); ++} ++ ++static void ++gam_kqueue_add_rm_handler(const char *path, GamSubscription *sub, gboolean added, gboolean was_missing) ++{ ++ KQueueData *data; ++ struct kevent ev[1]; ++ int isdir = 0; ++ int fd; ++ ++ G_LOCK(kqueue); ++ ++ isdir = g_file_test(path, G_FILE_TEST_IS_DIR); ++ if (gam_subscription_is_dir(sub)) { ++ data = g_hash_table_lookup(dir_path_hash, path); ++ } ++ else { ++ data = g_hash_table_lookup(file_path_hash, path); ++ } ++ ++ if (added) { ++ GList *subs; ++ ++ subs = NULL; ++ subs = g_list_append(subs, sub); ++ ++ if (data != NULL) { ++ data->refcount++; ++ data->subs = g_list_prepend(data->subs, sub); ++ G_UNLOCK(kqueue); ++ GAM_DEBUG(DEBUG_INFO, "kqueue updated refcount\n"); ++ if (!was_missing) { ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_EXISTS, subs, 1); ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_ENDEXISTS, subs, 1); ++ } ++ else { ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_CREATED, subs, 1); ++ } ++ return; ++ } ++ ++ if (!g_file_test(path, G_FILE_TEST_EXISTS)) { ++ data = gam_kqueue_data_new(path, -1); ++ data->subs = g_list_prepend(data->subs, sub); ++ exist_list = g_slist_append(exist_list, data); ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_DELETED, subs, 1); ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_ENDEXISTS, subs, 1); ++ G_UNLOCK(kqueue); ++ return; ++ } ++ ++ fd = open(path, O_RDONLY); ++ ++ if (fd < 0) { ++ G_UNLOCK(kqueue); ++ return; ++ } ++ ++ EV_SET(ev, fd, EVFILT_VNODE, ++ EV_ADD | EV_ENABLE | EV_CLEAR, VN_NOTE_ALL, 0, 0); ++ kevent(kq, ev, 1, NULL, 0, NULL); ++ ++ data = gam_kqueue_data_new(path, fd); ++ data->subs = g_list_prepend(data->subs, sub); ++ ++ if (!was_missing) { ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_EXISTS, subs, 1); ++ } ++ else { ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_CREATED, subs, 1); ++ } ++ if (gam_subscription_is_dir(sub) && isdir) { ++ GSList *l; ++ ++ data->isdir = TRUE; ++ data->dirlist = gam_kqueue_lsdir(path); ++ ++ for (l = data->dirlist; l; l = l->next) { ++ char *tmpentry; ++ ++ tmpentry = g_build_filename(path, l->data, NULL); ++ if (!was_missing) { ++ gam_server_emit_event (tmpentry, ++ g_file_test(tmpentry, G_FILE_TEST_IS_DIR), ++ GAMIN_EVENT_EXISTS, subs, 1); ++ } ++ g_free(tmpentry); ++ } ++ } ++ ++ if (!was_missing) { ++ gam_server_emit_event (path, isdir, GAMIN_EVENT_ENDEXISTS, subs, 1); ++ } ++ ++ g_hash_table_insert(fd_hash, GINT_TO_POINTER(data->fd), data); ++ if (data->isdir) { ++ g_hash_table_insert(dir_path_hash, data->path, data); ++ } ++ else { ++ g_hash_table_insert(file_path_hash, data->path, data); ++ } ++ ++ if (subs) ++ g_list_free(subs); ++ ++ GAM_DEBUG(DEBUG_INFO, "added kqueue watch for %s\n", path); ++ } else { ++ ++ if (!data) { ++ G_UNLOCK(kqueue); ++ return; ++ } ++ ++ if (g_list_find (data->subs, sub)) { ++ data->subs = g_list_remove_all (data->subs, sub); ++ } ++ data->refcount--; ++ GAM_DEBUG(DEBUG_INFO, "kqueue decremeneted refcount for %s\n", path); ++ ++ if (data->refcount == 0) { ++ GList *l; ++ ++ close(data->fd); ++ l = data->subs; ++ for (l = l; l; l = l->next) { ++ GamSubscription *sub = l->data; ++ gam_kqueue_remove_subscription (sub); ++ } ++ GAM_DEBUG(DEBUG_INFO, "removed kqueue watch for %s\n", data->path); ++ if (data->isdir) { ++ g_hash_table_remove(dir_path_hash, data->path); ++ } ++ else { ++ g_hash_table_remove(file_path_hash, data->path); ++ } ++ g_hash_table_remove(fd_hash, GINT_TO_POINTER(data->fd)); ++ gam_kqueue_data_free(data); ++ } ++ } ++ G_UNLOCK(kqueue); ++} ++ ++static GaminEventType kqueue_event_to_gamin_event (int mask) ++{ ++ if ((mask & VN_NOTE_CHANGED) != 0) ++ return GAMIN_EVENT_CHANGED; ++ else if ((mask & NOTE_DELETE) != 0) ++ return GAMIN_EVENT_DELETED; ++ else if ((mask & NOTE_REVOKE) != 0) ++ return GAMIN_EVENT_ENDEXISTS; ++ else if ((mask & NOTE_RENAME) != 0) ++ return GAMIN_EVENT_MOVED; ++ else ++ return GAMIN_EVENT_UNKNOWN; ++} ++ ++static void gam_kqueue_emit_event (KQueueData *data, struct kevent *event) ++{ ++ GaminEventType gevent; ++ int isdir = 0; ++ char *event_path; ++ ++ if (!data||!event) ++ return; ++ ++ gevent = kqueue_event_to_gamin_event (event->fflags); ++ ++ if (gevent == GAMIN_EVENT_UNKNOWN) { ++ return; ++ } ++ ++ isdir = g_file_test(data->path, G_FILE_TEST_IS_DIR); ++ ++ if (gevent == GAMIN_EVENT_CHANGED && data->isdir) { ++ GSList *dirlist = NULL, *added = NULL, *deleted = NULL; ++ GSList *l; ++ ++ dirlist = gam_kqueue_lsdir(data->path); ++ gam_kqueue_cmplst(data->dirlist, dirlist, &added, &deleted); ++ if (added || deleted) { ++ for (l = deleted; l; l = l->next) { ++ data->dirlist = g_slist_remove(data->dirlist, l->data); ++ event_path = g_build_filename(data->path, l->data, NULL); ++ g_free(l->data); ++ isdir = g_file_test(event_path, G_FILE_TEST_IS_DIR); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue emitting event %s for %s\n", gam_event_to_string(GAMIN_EVENT_DELETED) , event_path); ++ ++ gam_server_emit_event (event_path, isdir, ++ GAMIN_EVENT_DELETED, data->subs, 1); ++ g_free(event_path); ++ } ++ ++ for (l = added; l; l = l->next) { ++ dirlist = g_slist_remove(dirlist, l->data); ++ data->dirlist = g_slist_prepend(data->dirlist, ++ g_strdup(l->data)); ++ event_path = g_build_filename(data->path, l->data, NULL); ++ g_free(l->data); ++ isdir = g_file_test(event_path, G_FILE_TEST_IS_DIR); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue emitting event %s for %s\n", gam_event_to_string(GAMIN_EVENT_CREATED) , event_path); ++ ++ gam_server_emit_event (event_path, isdir, ++ GAMIN_EVENT_CREATED, data->subs, 1); ++ g_free(event_path); ++ } ++ ++ if (added) ++ g_slist_free(added); ++ if (deleted) ++ g_slist_free(deleted); ++ } ++ ++ if (dirlist) { ++ g_slist_foreach(dirlist, (GFunc)g_free, NULL); ++ g_slist_free(dirlist); ++ } ++ return; ++ } ++ else { ++ event_path = g_strdup (data->path); ++ } ++ ++ isdir = g_file_test(event_path, G_FILE_TEST_IS_DIR); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue emitting event %s for %s\n", gam_event_to_string(gevent) , event_path); ++ ++ gam_server_emit_event (event_path, isdir, gevent, data->subs, 1); ++ ++ g_free (event_path); ++} ++ ++static gboolean ++gam_kqueue_exist_check (gpointer user_data) ++{ ++ GSList *l, *tmplst; ++ KQueueData *data; ++ ++ tmplst = g_slist_copy(exist_list); ++ ++ for (l = tmplst; l; l = l->next) { ++ data = l->data; ++ ++ if (g_file_test(data->path, G_FILE_TEST_EXISTS)) { ++ /* The subs list is guaranteed to have only one entry. */ ++ GamSubscription *sub = data->subs->data; ++ ++ exist_list = g_slist_remove(exist_list, data); ++ gam_kqueue_add_rm_handler(data->path, sub, TRUE, TRUE); ++ gam_kqueue_data_free(data); ++ } ++ } ++ ++ if (tmplst) ++ g_slist_free(tmplst); ++ ++ return TRUE; ++} ++ ++static gboolean ++gam_kqueue_event_handler (gpointer user_data) ++{ ++ KQueueData *data; ++ struct kevent ev[1]; ++ struct timespec timeout = { 0, 0 }; ++ int fd, i, nevents; ++ ++ G_LOCK(kqueue); ++ ++ GAM_DEBUG(DEBUG_INFO, "gam_kqueue_event_handler()\n"); ++ ++ nevents = kevent(kq, NULL, 0, ev, 1, &timeout); ++ if (nevents == -1) ++ return FALSE; ++ for (i = 0; i < nevents; i++) { ++ fd = ev[i].ident; ++ ++ data = g_hash_table_lookup (fd_hash, GINT_TO_POINTER(fd)); ++ if (!data) { ++ GAM_DEBUG(DEBUG_INFO, "kqueue can't find fd %d\n", fd); ++ GAM_DEBUG(DEBUG_INFO, "weird things have happened to kqueue.\n"); ++ } else { ++ gam_kqueue_emit_event (data, &ev[i]); ++ } ++ ++ } ++ ++ G_UNLOCK(kqueue); ++ ++ return TRUE; ++} ++ ++static gboolean ++gam_kqueue_consume_subscriptions_real(gpointer data) ++{ ++ GList *subs, *l; ++ ++ G_LOCK(new_subs); ++ if (new_subs) { ++ subs = new_subs; ++ new_subs = NULL; ++ G_UNLOCK(new_subs); ++ ++ for (l = subs; l; l = l->next) { ++ GamSubscription *sub = l->data; ++ GAM_DEBUG(DEBUG_INFO, "called gam_kqueue_add_handler()\n"); ++ gam_kqueue_add_rm_handler (gam_subscription_get_path (sub), sub, TRUE, FALSE); ++ } ++ ++ } else { ++ G_UNLOCK(new_subs); ++ } ++ ++ G_LOCK(removed_subs); ++ if (removed_subs) { ++ subs = removed_subs; ++ removed_subs = NULL; ++ G_UNLOCK(removed_subs); ++ ++ for (l = subs; l; l = l->next) { ++ GamSubscription *sub = l->data; ++ GAM_DEBUG(DEBUG_INFO, "called gam_kqueue_rm_handler()\n"); ++ gam_kqueue_add_rm_handler (gam_subscription_get_path (sub), sub, FALSE, FALSE); ++ } ++ } else { ++ G_UNLOCK(removed_subs); ++ } ++ ++ GAM_DEBUG(DEBUG_INFO, "gam_kqueue_consume_subscriptions()\n"); ++ ++ have_consume_idler = FALSE; ++ return FALSE; ++} ++ ++static void ++gam_kqueue_consume_subscriptions(void) ++{ ++ GSource *source; ++ ++ if (have_consume_idler) ++ return; ++ ++ have_consume_idler = TRUE; ++ ++ source = g_idle_source_new (); ++ g_source_set_callback (source, gam_kqueue_consume_subscriptions_real, NULL, NULL); ++ ++ g_source_attach (source, NULL); ++} ++ ++/** ++ * @defgroup kqueue kqueue backend ++ * @ingroup Backends ++ * @brief kqueue backend API ++ * ++ * Since 4.1, FreeBSD kernels have included the kernel event notification ++ * machanism (kqueue). This backend uses kqueue to know when ++ * files are changed/created/deleted. ++ * ++ * @{ ++ */ ++ ++ ++/** ++ * Initializes the kqueue system. This must be called before ++ * any other functions in this module. ++ * ++ * @returns TRUE if initialization succeeded, FALSE otherwise ++ */ ++gboolean ++gam_kqueue_init(void) ++{ ++ kq = kqueue(); ++ if (kq == -1) { ++ GAM_DEBUG(DEBUG_INFO, "Could not initialize a new kqueue\n"); ++ return FALSE; ++ } ++ ++ g_timeout_add(1000, gam_kqueue_exist_check, NULL); ++ g_timeout_add(1000, gam_kqueue_event_handler, NULL); ++ ++ dir_path_hash = g_hash_table_new(g_str_hash, g_str_equal); ++ file_path_hash = g_hash_table_new(g_str_hash, g_str_equal); ++ fd_hash = g_hash_table_new(g_direct_hash, g_direct_equal); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue initialized\n"); ++ ++ gam_backend_add_subscription = gam_kqueue_add_subscription; ++ gam_backend_remove_subscription = gam_kqueue_remove_subscription; ++ gam_backend_remove_all_for = gam_kqueue_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_kqueue_add_subscription(GamSubscription * sub) ++{ ++ gam_listener_add_subscription(gam_subscription_get_listener(sub), sub); ++ ++ G_LOCK(new_subs); ++ new_subs = g_list_prepend(new_subs, sub); ++ G_UNLOCK(new_subs); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue_add_sub\n"); ++ ++ gam_kqueue_consume_subscriptions(); ++ 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_kqueue_remove_subscription(GamSubscription * sub) ++{ ++ G_LOCK(new_subs); ++ if (g_list_find(new_subs, sub)) { ++ GAM_DEBUG(DEBUG_INFO, "removed sub found on new_subs\n"); ++ new_subs = g_list_remove_all (new_subs, sub); ++ G_UNLOCK(new_subs); ++ return TRUE; ++ } ++ G_UNLOCK(new_subs); ++ ++ gam_subscription_cancel (sub); ++ gam_listener_remove_subscription(gam_subscription_get_listener(sub), sub); ++ ++ G_LOCK(removed_subs); ++ removed_subs = g_list_prepend (removed_subs, sub); ++ G_UNLOCK(removed_subs); ++ ++ GAM_DEBUG(DEBUG_INFO, "kqueue_remove_sub\n"); ++ gam_kqueue_consume_subscriptions(); ++ ++ 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_kqueue_remove_all_for(GamListener * listener) ++{ ++ GList *subs, *l = NULL; ++ ++ subs = gam_listener_get_subscriptions (listener); ++ ++ for (l = subs; l; l = l->next) { ++ GamSubscription *sub = l->data; ++ ++ g_assert (sub != NULL); ++ ++ gam_kqueue_remove_subscription (sub); ++ ++ } ++ ++ if (subs) { ++ g_list_free (subs); ++ gam_kqueue_consume_subscriptions(); ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/** @} */ diff --git a/devel/gamin/files/patch-server_gam_kqueue.h b/devel/gamin/files/patch-server_gam_kqueue.h new file mode 100644 index 000000000000..c99f5e3ee380 --- /dev/null +++ b/devel/gamin/files/patch-server_gam_kqueue.h @@ -0,0 +1,27 @@ +--- server/gam_kqueue.h.orig Sat Mar 26 18:32:19 2005 ++++ server/gam_kqueue.h Sat Mar 26 18:36:11 2005 +@@ -0,0 +1,24 @@ ++ ++#ifndef __MD_KQUEUE_H__ ++#define __MD_KQUEUE_H__ ++ ++#include ++#include "gam_poll.h" ++#include "gam_subscription.h" ++ ++#define VN_NOTE_MOST (NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | \ ++ NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | \ ++ NOTE_REVOKE) ++#define VN_NOTE_ALL VN_NOTE_MOST ++#define VN_NOTE_CHANGED (NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK) ++ ++G_BEGIN_DECLS ++ ++gboolean gam_kqueue_init (void); ++gboolean gam_kqueue_add_subscription (GamSubscription *sub); ++gboolean gam_kqueue_remove_subscription (GamSubscription *sub); ++gboolean gam_kqueue_remove_all_for (GamListener *listener); ++ ++G_END_DECLS ++ ++#endif /* __MD_KQUEUE_H__ */ diff --git a/devel/gamin/files/patch-server_gam_server.c b/devel/gamin/files/patch-server_gam_server.c new file mode 100644 index 000000000000..de62120f6ff6 --- /dev/null +++ b/devel/gamin/files/patch-server_gam_server.c @@ -0,0 +1,56 @@ +--- server/gam_server.c.orig Thu Dec 2 12:42:56 2004 ++++ server/gam_server.c Sun Mar 27 02:34:19 2005 +@@ -39,12 +39,29 @@ + #ifdef ENABLE_DNOTIFY + #include "gam_dnotify.h" + #endif ++#ifdef ENABLE_KQUEUE ++#include "gam_kqueue.h" ++#endif + #include "gam_excludes.h" + + static int poll_only = 0; + static const char *session; + + /** ++ * gam_exit: ++ * ++ * Call the shutdown routine, then just exit. ++ * This function is designed to be called from a ++ * signal handler. ++ */ ++void ++gam_exit(int signo) { ++ gam_shutdown(); ++ ++ exit(0); ++} ++ ++/** + * gam_shutdown: + * + * Shutdown routine called when the server exits +@@ -90,6 +107,12 @@ gam_init_subscriptions(void) + return(TRUE); + } + #endif ++#ifdef ENABLE_KQUEUE ++ if (gam_kqueue_init()) { ++ GAM_DEBUG(DEBUG_INFO, "Using KQueue as backend\n"); ++ return(TRUE); ++ } ++#endif + } + if (gam_poll_init()) { + GAM_DEBUG(DEBUG_INFO, "Using Poll as backend\n"); +@@ -332,6 +355,10 @@ main(int argc, const char *argv[]) + } + + gam_error_init(); ++ signal(SIGHUP, gam_exit); ++ signal(SIGINT, gam_exit); ++ signal(SIGQUIT, gam_exit); ++ signal(SIGTERM, gam_exit); + signal(SIGPIPE, SIG_IGN); + + if (!gam_init_subscriptions()) { diff --git a/devel/gamin/pkg-descr b/devel/gamin/pkg-descr new file mode 100644 index 000000000000..ac16e95d121f --- /dev/null +++ b/devel/gamin/pkg-descr @@ -0,0 +1,5 @@ +Gamin is a file and directory monitoring system defined to be a subset of the +FAM (File Alteration Monitor) system. This is a service provided by a library +which allows to detect when a file or a directory has been modified. + +WWW: http://www.gnome.org/~veillard/gamin/index.html diff --git a/devel/gamin/pkg-plist b/devel/gamin/pkg-plist new file mode 100644 index 000000000000..d318e2257d82 --- /dev/null +++ b/devel/gamin/pkg-plist @@ -0,0 +1,10 @@ +include/fam.h +lib/libfam.a +lib/libfam.so +lib/libfam.so.0 +lib/libgamin-1.a +lib/libgamin-1.so +lib/libgamin-1.so.0 +lib/libgamin_shared.a +libdata/pkgconfig/gamin.pc +libexec/gam_server