--- devel/glib20/Makefile (revision 483820) +++ devel/glib20/Makefile (working copy) @@ -48,11 +48,16 @@ glib-compile-resources.1 gresource.1 gdbus-codegen.1 gobject_MAN= glib-genmarshal.1 glib-mkenums.1 gobject-query.1 -OPTIONS_DEFINE= DEBUG NLS +OPTIONS_DEFINE= DEBUG FAM_ALTBACKEND NLS OPTIONS_SUB= yes DEBUG_CONFIGURE_ON= --enable-debug=yes +FAM_ALTBACKEND_DESC= Alternate file monitor backend +#FAM_ALTBACKEND_USES= autoreconf:build +FAM_ALTBACKEND_EXTRA_PATCHES= ${FILESDIR}/extra-patch-gio_kqueue_Makefile.am + + .include # doesn't build yet @@ -86,6 +91,13 @@ s|-Werror|| ; \ s|#define HAVE_SYS_INOTIFY_H 1||' ${WRKSRC}/configure +pre-configure-FAM_ALTBACKEND-on: + @${CP} -f ${FILESDIR}/gkqueuefilemonitor.c ${WRKSRC}/gio/kqueue/gkqueuefilemonitor.c + @${CP} -f ${FILESDIR}/kqueue_Makefile.in ${WRKSRC}/gio/kqueue/Makefile.in + @${CP} ${FILESDIR}/kqueue_fnm.c ${WRKSRC}/gio/kqueue/kqueue_fnm.c + @${CP} ${FILESDIR}/kqueue_fnm.h ${WRKSRC}/gio/kqueue/kqueue_fnm.h + #@(cd ${WRKSRC} && ${AUTORECONF} -fvi) + post-install: @${MKDIR} ${STAGEDIR}${PREFIX}/share/GConf/gsettings @${MKDIR} ${STAGEDIR}${PREFIX}/lib/gio/modules --- devel/glib20/files/extra-patch-gio_kqueue_Makefile.am (nonexistent) +++ devel/glib20/files/extra-patch-gio_kqueue_Makefile.am (working copy) @@ -0,0 +1,26 @@ +--- gio/kqueue/Makefile.am.orig 2015-10-14 14:41:16.000000000 +0300 ++++ gio/kqueue/Makefile.am 2016-11-06 05:08:37.646089000 +0300 +@@ -4,21 +4,8 @@ + + libkqueue_la_SOURCES = \ + gkqueuefilemonitor.c \ +- gkqueuefilemonitor.h \ +- kqueue-helper.c \ +- kqueue-helper.h \ +- kqueue-thread.c \ +- kqueue-thread.h \ +- kqueue-sub.c \ +- kqueue-sub.h \ +- kqueue-missing.c \ +- kqueue-missing.h \ +- kqueue-utils.c \ +- kqueue-utils.h \ +- kqueue-exclusions.c \ +- kqueue-exclusions.h \ +- dep-list.c \ +- dep-list.h \ ++ kqueue_fnm.c \ ++ kqueue_fnm.h \ + $(NULL) + + libkqueue_la_CFLAGS = \ --- devel/glib20/files/gkqueuefilemonitor.c (nonexistent) +++ devel/glib20/files/gkqueuefilemonitor.c (working copy) @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2016 - 2018 Rozhuk Ivan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Rozhuk Ivan + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include "glib-private.h" +#include +#include "kqueue_fnm.h" + +/* Defaults. */ +#ifndef KQUEUE_MON_RATE_LIMIT_TIME_INIT +# define KQUEUE_MON_RATE_LIMIT_TIME_INIT 1000 +#endif +#ifndef KQUEUE_MON_RATE_LIMIT_TIME_MAX +# define KQUEUE_MON_RATE_LIMIT_TIME_MAX 8000 +#endif +#ifndef KQUEUE_MON_RATE_LIMIT_TIME_MUL +# define KQUEUE_MON_RATE_LIMIT_TIME_MUL 2 +#endif +#ifndef KQUEUE_MON_MAX_DIR_FILES +# define KQUEUE_MON_MAX_DIR_FILES 128 +#endif +#ifndef KQUEUE_MON_LOCAL_SUBFILES +# define KQUEUE_MON_LOCAL_SUBFILES 1 +#endif +#ifndef KQUEUE_MON_LOCAL_SUBDIRS +# define KQUEUE_MON_LOCAL_SUBDIRS 0 +#endif + + +static GMutex kqueue_lock; +static volatile kq_fnm_p kqueue_fnm = NULL; +/* Exclude from file changes monitoring, watch only for dirs. */ +static const char *non_local_fs[] = { + "fusefs.sshfs", + NULL +}; + +#define G_TYPE_KQUEUE_FILE_MONITOR (g_kqueue_file_monitor_get_type()) +#define G_KQUEUE_FILE_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST((inst), \ + G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor)) + +typedef GLocalFileMonitorClass GKqueueFileMonitorClass; + +typedef struct { + GLocalFileMonitor parent_instance; + kq_fnmo_p fnmo; +} GKqueueFileMonitor; + +GType g_kqueue_file_monitor_get_type(void); +G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, + g_io_extension_point_implement(G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "kqueue", + 10)) + + +static void +kqueue_event_handler(kq_fnm_p kfnm, + kq_fnmo_p fnmo, void *udata, uint32_t event, + const char *base, const char *filename, const char *new_filename) { + static const uint32_t kfnm_to_glib_map[] = { + 0, /* KF_EVENT_NOT_CHANGED */ + G_FILE_MONITOR_EVENT_CREATED, /* KF_EVENT_CREATED */ + G_FILE_MONITOR_EVENT_DELETED, /* KF_EVENT_DELETED */ + G_FILE_MONITOR_EVENT_RENAMED, /* KF_EVENT_RENAMED */ + G_FILE_MONITOR_EVENT_CHANGED /* KF_EVENT_CHANGED */ + }; + + if (NULL == kfnm || NULL == filename || + KF_EVENT_CREATED > event || + KF_EVENT_CHANGED < event) + return; + g_file_monitor_source_handle_event(udata, + kfnm_to_glib_map[event], + filename, new_filename, NULL, + g_get_monotonic_time()); +} + +static gboolean +g_kqueue_file_monitor_is_supported(void) { + kq_file_mon_settings_t kfms; + + if (NULL != kqueue_fnm) + return (TRUE); + /* Init only once. */ + g_mutex_lock(&kqueue_lock); + if (NULL != kqueue_fnm) { + g_mutex_unlock(&kqueue_lock); + return (TRUE); /* Initialized while wait lock. */ + } + + memset(&kfms, 0x00, sizeof(kq_file_mon_settings_t)); + kfms.rate_limit_time_init = KQUEUE_MON_RATE_LIMIT_TIME_INIT; + kfms.rate_limit_time_max = KQUEUE_MON_RATE_LIMIT_TIME_MAX; + kfms.rate_limit_time_mul = KQUEUE_MON_RATE_LIMIT_TIME_MUL; + kfms.max_dir_files = KQUEUE_MON_MAX_DIR_FILES; + kfms.mon_local_subfiles = KQUEUE_MON_LOCAL_SUBFILES; + kfms.mon_local_subdirs = KQUEUE_MON_LOCAL_SUBDIRS; + kfms.local_fs = NULL; + kfms.non_local_fs = non_local_fs; + + kqueue_fnm = kq_fnm_create(&kfms, kqueue_event_handler); + if (NULL == kqueue_fnm) { + g_mutex_unlock(&kqueue_lock); + return (FALSE); /* Init fail. */ + } + g_mutex_unlock(&kqueue_lock); + + return (TRUE); +} + +static gboolean +g_kqueue_file_monitor_cancel(GFileMonitor *monitor) { + GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(monitor); + + kq_fnm_del(kqueue_fnm, gffm->fnmo); + gffm->fnmo = NULL; + + return (TRUE); +} + +static void +g_kqueue_file_monitor_finalize(GObject *object) { + //GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(object); + + //g_mutex_lock(&kqueue_lock); + //kq_fnm_free(kqueue_fnm); + //kqueue_fnm = NULL; + //g_mutex_unlock(&kqueue_lock); + //G_OBJECT_CLASS(g_kqueue_file_monitor_parent_class)->finalize(object); +} + +static void +g_kqueue_file_monitor_start(GLocalFileMonitor *local_monitor, + const gchar *dirname, const gchar *basename, + const gchar *filename, GFileMonitorSource *source) { + GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(local_monitor); + + g_assert(NULL != kqueue_fnm); + //g_source_ref((GSource*)source); + + if (NULL == filename) { + filename = dirname; + } + gffm->fnmo = kq_fnm_add(kqueue_fnm, filename, source); +} + +static void +g_kqueue_file_monitor_init(GKqueueFileMonitor *monitor) { + +} + +static void +g_kqueue_file_monitor_class_init(GKqueueFileMonitorClass *class) { + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS(class); + + class->is_supported = g_kqueue_file_monitor_is_supported; + class->start = g_kqueue_file_monitor_start; + class->mount_notify = TRUE; /* TODO: ??? */ + file_monitor_class->cancel = g_kqueue_file_monitor_cancel; + gobject_class->finalize = g_kqueue_file_monitor_finalize; +} + +static void +g_kqueue_file_monitor_class_finalize(GKqueueFileMonitorClass *class) { + +} + +void +g_io_module_load(GIOModule *module) { + + g_type_module_use(G_TYPE_MODULE(module)); + + g_io_extension_point_implement(G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + G_TYPE_KQUEUE_FILE_MONITOR, "kqueue", 10); + g_io_extension_point_implement(G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME, + G_TYPE_KQUEUE_FILE_MONITOR, "kqueue", 10); +} + +void +g_io_module_unload(GIOModule *module) { + + g_assert_not_reached(); +} --- devel/glib20/files/kqueue_Makefile.in (nonexistent) +++ devel/glib20/files/kqueue_Makefile.in (working copy) @@ -0,0 +1,1533 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# GLIB - Library of useful C routines + + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +installed_test_PROGRAMS = $(am__EXEEXT_1) +noinst_PROGRAMS = $(am__EXEEXT_3) +check_PROGRAMS = $(am__EXEEXT_2) +TESTS = $(am__EXEEXT_1) +@OS_WIN32_TRUE@am__append_1 = $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \ +@OS_WIN32_TRUE@ $(dist_test_scripts) $(dist_uninstalled_test_scripts) + +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_2 = $(all_test_ltlibs) +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_3 = $(all_test_programs) +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_4 = $(all_test_scripts) +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_5 = $(all_test_data) +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_6 = $(all_test_ltlibs) +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_7 = $(all_test_programs) +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_8 = $(all_test_scripts) +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_9 = $(all_test_data) +@ENABLE_INSTALLED_TESTS_TRUE@am__append_10 = $(test_programs) $(installed_test_programs) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(test_extra_programs) $(installed_test_extra_programs) + +@ENABLE_INSTALLED_TESTS_TRUE@am__append_11 = $(test_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(installed_test_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(test_extra_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(test_installed_extra_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_test_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_test_extra_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_installed_test_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_installed_test_extra_scripts) +@ENABLE_INSTALLED_TESTS_TRUE@am__append_12 = $(test_data) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(installed_test_data) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_test_data) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_installed_test_data) +@ENABLE_INSTALLED_TESTS_TRUE@am__append_13 = $(test_ltlibraries) $(installed_test_ltlibraries) +@ENABLE_INSTALLED_TESTS_TRUE@am__append_14 = $(installed_test_meta_DATA) +subdir = gio/kqueue +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/attributes.m4 \ + $(top_srcdir)/m4macros/glibtests.m4 \ + $(top_srcdir)/m4macros/gtk-doc.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/acglib.m4 \ + $(top_srcdir)/glib/libcharset/codeset.m4 \ + $(top_srcdir)/glib/libcharset/glibc21.m4 \ + $(top_srcdir)/m4macros/glib-gettext.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_2 = $(am__EXEEXT_1) +am__installdirs = "$(DESTDIR)$(installed_testdir)" \ + "$(DESTDIR)$(installed_testdir)" \ + "$(DESTDIR)$(installed_testdir)" \ + "$(DESTDIR)$(installed_test_metadir)" \ + "$(DESTDIR)$(installed_testdir)" +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_3 = $(am__EXEEXT_1) +PROGRAMS = $(installed_test_PROGRAMS) $(noinst_PROGRAMS) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +LTLIBRARIES = $(installed_test_LTLIBRARIES) $(noinst_LTLIBRARIES) +libkqueue_la_LIBADD = +am__objects_1 = +am_libkqueue_la_OBJECTS = libkqueue_la-gkqueuefilemonitor.lo \ + libkqueue_la-kqueue_fnm.lo $(am__objects_1) +libkqueue_la_OBJECTS = $(am_libkqueue_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libkqueue_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libkqueue_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SCRIPTS = $(installed_test_SCRIPTS) $(noinst_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo \ + ./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libkqueue_la_SOURCES) +DIST_SOURCES = $(libkqueue_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(installed_test_meta_DATA) $(nobase_installed_test_DATA) \ + $(noinst_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/glib.mk $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABS_TAPSET_DIR = @ABS_TAPSET_DIR@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CARBON_LIBS = @CARBON_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COCOA_LIBS = @COCOA_LIBS@ +CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS1_CFLAGS = @DBUS1_CFLAGS@ +DBUS1_LIBS = @DBUS1_LIBS@ +DBUS_DAEMON = @DBUS_DAEMON@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO = @GIO@ +GIO_MODULE_DIR = @GIO_MODULE_DIR@ +GLIBC21 = @GLIBC21@ +GLIB_BINARY_AGE = @GLIB_BINARY_AGE@ +GLIB_DEBUG_FLAGS = @GLIB_DEBUG_FLAGS@ +GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@ +GLIB_HIDDEN_VISIBILITY_CFLAGS = @GLIB_HIDDEN_VISIBILITY_CFLAGS@ +GLIB_INTERFACE_AGE = @GLIB_INTERFACE_AGE@ +GLIB_LINK_FLAGS = @GLIB_LINK_FLAGS@ +GLIB_MAJOR_VERSION = @GLIB_MAJOR_VERSION@ +GLIB_MICRO_VERSION = @GLIB_MICRO_VERSION@ +GLIB_MINOR_VERSION = @GLIB_MINOR_VERSION@ +GLIB_RUNTIME_LIBDIR = @GLIB_RUNTIME_LIBDIR@ +GLIB_VERSION = @GLIB_VERSION@ +GLIB_WARN_CFLAGS = @GLIB_WARN_CFLAGS@ +GLIB_WIN32_STATIC_COMPILATION_DEFINE = @GLIB_WIN32_STATIC_COMPILATION_DEFINE@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GSPAWN = @GSPAWN@ +GTHREAD_COMPILE_IMPL_DEFINES = @GTHREAD_COMPILE_IMPL_DEFINES@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +G_LIBS_EXTRA = @G_LIBS_EXTRA@ +G_MODULE_BROKEN_RTLD_GLOBAL = @G_MODULE_BROKEN_RTLD_GLOBAL@ +G_MODULE_HAVE_DLERROR = @G_MODULE_HAVE_DLERROR@ +G_MODULE_IMPL = @G_MODULE_IMPL@ +G_MODULE_LDFLAGS = @G_MODULE_LDFLAGS@ +G_MODULE_LIBS = @G_MODULE_LIBS@ +G_MODULE_LIBS_EXTRA = @G_MODULE_LIBS_EXTRA@ +G_MODULE_NEED_USCORE = @G_MODULE_NEED_USCORE@ +G_MODULE_PLUGIN_LIBS = @G_MODULE_PLUGIN_LIBS@ +G_MODULE_SUPPORTED = @G_MODULE_SUPPORTED@ +G_THREAD_CFLAGS = @G_THREAD_CFLAGS@ +G_THREAD_LIBS = @G_THREAD_LIBS@ +G_THREAD_LIBS_EXTRA = @G_THREAD_LIBS_EXTRA@ +G_THREAD_LIBS_FOR_GTHREAD = @G_THREAD_LIBS_FOR_GTHREAD@ +HTML_DIR = @HTML_DIR@ +ICONV_LIBS = @ICONV_LIBS@ +INDENT = @INDENT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBELF_CFLAGS = @LIBELF_CFLAGS@ +LIBELF_LIBS = @LIBELF_LIBS@ +LIBFFI_CFLAGS = @LIBFFI_CFLAGS@ +LIBFFI_LIBS = @LIBFFI_LIBS@ +LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@ +LIBMOUNT_LIBS = @LIBMOUNT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_EXE_MACHINE_FLAG = @LIB_EXE_MACHINE_FLAG@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LTP = @LTP@ +LTP_GENHTML = @LTP_GENHTML@ +LT_AGE = @LT_AGE@ +LT_CURRENT = @LT_CURRENT@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +NAMESER_COMPAT_INCLUDE = @NAMESER_COMPAT_INCLUDE@ +NETWORK_LIBS = @NETWORK_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE_CFLAGS = @PCRE_CFLAGS@ +PCRE_LIBS = @PCRE_LIBS@ +PCRE_REQUIRES = @PCRE_REQUIRES@ +PCRE_WARN_CFLAGS = @PCRE_WARN_CFLAGS@ +PERL = @PERL@ +PERL_PATH = @PERL_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLATFORMDEP = @PLATFORMDEP@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +REBUILD = @REBUILD@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHTOOL = @SHTOOL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +WSPIAPI_INCLUDE = @WSPIAPI_INCLUDE@ +XATTR_LIBS = @XATTR_LIBS@ +XGETTEXT = @XGETTEXT@ +XMLCATALOG = @XMLCATALOG@ +XML_CATALOG_FILE = @XML_CATALOG_FILE@ +XSLTPROC = @XSLTPROC@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +config_h_INCLUDES = @config_h_INCLUDES@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gio_INCLUDES = @gio_INCLUDES@ +glib_INCLUDES = @glib_INCLUDES@ +gmodule_INCLUDES = @gmodule_INCLUDES@ +gobject_INCLUDES = @gobject_INCLUDES@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +installed_test_metadir = @installed_test_metadir@ +installed_testdir = @installed_testdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +#GTESTER = gtester # for non-GLIB packages +#GTESTER_REPORT = gtester-report # for non-GLIB packages +GTESTER = $(top_builddir)/glib/gtester # for the GLIB package +GTESTER_REPORT = $(top_builddir)/glib/gtester-report # for the GLIB package +NULL = + +# initialize variables for unconditional += appending +BUILT_SOURCES = +BUILT_EXTRA_DIST = +CLEANFILES = *.log *.trs $(am__append_14) +DISTCLEANFILES = +MAINTAINERCLEANFILES = +EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) + +# We support a fairly large range of possible variables. It is expected that all types of files in a test suite +# will belong in exactly one of the following variables. +# +# First, we support the usual automake suffixes, but in lowercase, with the customary meaning: +# +# test_programs, test_scripts, test_data, test_ltlibraries +# +# The above are used to list files that are involved in both uninstalled and installed testing. The +# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite. +# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is +# installed in the same way as it appears in the package layout. +# +# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled', +# like so: +# +# installed_test_programs, uninstalled_test_programs +# installed_test_scripts, uninstalled_test_scripts +# installed_test_data, uninstalled_test_data +# installed_test_ltlibraries, uninstalled_test_ltlibraries +# +# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts +# that should not themselves be run as testcases (but exist to be used from other testcases): +# +# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs +# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts +# +# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data +# file automatically end up in the tarball. +# +# dist_test_scripts, dist_test_data, dist_test_extra_scripts +# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts +# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts +# +# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the +# standard automake convention of not disting programs scripts or data by default. +# +# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted +# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under +# gtester. That's a bit strange for scripts, but it's possible. + +# we use test -z "$(TEST_PROGS)" above, so make sure we have no extra whitespace... +TEST_PROGS = $(strip $(test_programs) $(test_scripts) \ + $(uninstalled_test_programs) $(uninstalled_test_scripts) \ + $(dist_test_scripts) $(dist_uninstalled_test_scripts)) +installed_test_LTLIBRARIES = $(am__append_13) +installed_test_SCRIPTS = $(am__append_11) +nobase_installed_test_DATA = $(am__append_12) +noinst_LTLIBRARIES = $(am__append_2) libkqueue.la +noinst_SCRIPTS = $(am__append_4) +noinst_DATA = $(am__append_5) +check_LTLIBRARIES = $(am__append_6) +check_SCRIPTS = $(am__append_8) +check_DATA = $(am__append_9) + +# Note: build even the installed-only targets during 'make check' to ensure that they still work. +# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to +# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were +# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'. +all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \ + $(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs) + +all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) \ + $(installed_test_scripts) $(test_extra_scripts) \ + $(uninstalled_test_extra_scripts) \ + $(installed_test_extra_scripts) $(all_dist_test_scripts) +all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \ + $(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts) + +all_test_data = $(test_data) $(uninstalled_test_data) \ + $(installed_test_data) $(all_dist_test_data) +all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data) +all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries) +@ENABLE_INSTALLED_TESTS_TRUE@installed_testcases = $(test_programs) $(installed_test_programs) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(test_scripts) $(installed_test_scripts) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(dist_test_scripts) $(dist_installed_test_scripts) + +@ENABLE_INSTALLED_TESTS_TRUE@installed_test_meta_DATA = $(installed_testcases:=.test) +libkqueue_la_SOURCES = \ + gkqueuefilemonitor.c \ + kqueue_fnm.c \ + kqueue_fnm.h \ + $(NULL) + +libkqueue_la_CFLAGS = \ + $(GLIB_HIDDEN_VISIBILITY_CFLAGS) \ + -DG_LOG_DOMAIN=\"GLib-GIO\" \ + $(gio_INCLUDES) \ + $(GLIB_DEBUG_FLAGS) \ + -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \ + -DGIO_COMPILATION \ + -DG_DISABLE_DEPRECATED + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/glib.mk $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gio/kqueue/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu gio/kqueue/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/glib.mk $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-installed_testPROGRAMS: $(installed_test_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(installed_test_PROGRAMS)'; test -n "$(installed_testdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(installed_testdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(installed_testdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-installed_testPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(installed_test_PROGRAMS)'; test -n "$(installed_testdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(installed_testdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(installed_testdir)" && rm -f $$files + +clean-installed_testPROGRAMS: + @list='$(installed_test_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-installed_testLTLIBRARIES: $(installed_test_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(installed_test_LTLIBRARIES)'; test -n "$(installed_testdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(installed_testdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(installed_testdir)"; \ + } + +uninstall-installed_testLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(installed_test_LTLIBRARIES)'; test -n "$(installed_testdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(installed_testdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(installed_testdir)/$$f"; \ + done + +clean-installed_testLTLIBRARIES: + -test -z "$(installed_test_LTLIBRARIES)" || rm -f $(installed_test_LTLIBRARIES) + @list='$(installed_test_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libkqueue.la: $(libkqueue_la_OBJECTS) $(libkqueue_la_DEPENDENCIES) $(EXTRA_libkqueue_la_DEPENDENCIES) + $(AM_V_CCLD)$(libkqueue_la_LINK) $(libkqueue_la_OBJECTS) $(libkqueue_la_LIBADD) $(LIBS) +install-installed_testSCRIPTS: $(installed_test_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(installed_test_SCRIPTS)'; test -n "$(installed_testdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(installed_testdir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(installed_testdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-installed_testSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(installed_test_SCRIPTS)'; test -n "$(installed_testdir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(installed_testdir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libkqueue_la-gkqueuefilemonitor.lo: gkqueuefilemonitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkqueue_la_CFLAGS) $(CFLAGS) -MT libkqueue_la-gkqueuefilemonitor.lo -MD -MP -MF $(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Tpo -c -o libkqueue_la-gkqueuefilemonitor.lo `test -f 'gkqueuefilemonitor.c' || echo '$(srcdir)/'`gkqueuefilemonitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Tpo $(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gkqueuefilemonitor.c' object='libkqueue_la-gkqueuefilemonitor.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkqueue_la_CFLAGS) $(CFLAGS) -c -o libkqueue_la-gkqueuefilemonitor.lo `test -f 'gkqueuefilemonitor.c' || echo '$(srcdir)/'`gkqueuefilemonitor.c + +libkqueue_la-kqueue_fnm.lo: kqueue_fnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkqueue_la_CFLAGS) $(CFLAGS) -MT libkqueue_la-kqueue_fnm.lo -MD -MP -MF $(DEPDIR)/libkqueue_la-kqueue_fnm.Tpo -c -o libkqueue_la-kqueue_fnm.lo `test -f 'kqueue_fnm.c' || echo '$(srcdir)/'`kqueue_fnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkqueue_la-kqueue_fnm.Tpo $(DEPDIR)/libkqueue_la-kqueue_fnm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kqueue_fnm.c' object='libkqueue_la-kqueue_fnm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkqueue_la_CFLAGS) $(CFLAGS) -c -o libkqueue_la-kqueue_fnm.lo `test -f 'kqueue_fnm.c' || echo '$(srcdir)/'`kqueue_fnm.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-installed_test_metaDATA: $(installed_test_meta_DATA) + @$(NORMAL_INSTALL) + @list='$(installed_test_meta_DATA)'; test -n "$(installed_test_metadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_test_metadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_test_metadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(installed_test_metadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(installed_test_metadir)" || exit $$?; \ + done + +uninstall-installed_test_metaDATA: + @$(NORMAL_UNINSTALL) + @list='$(installed_test_meta_DATA)'; test -n "$(installed_test_metadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(installed_test_metadir)'; $(am__uninstall_files_from_dir) +install-nobase_installed_testDATA: $(nobase_installed_test_DATA) + @$(NORMAL_INSTALL) + @list='$(nobase_installed_test_DATA)'; test -n "$(installed_testdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(installed_testdir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(installed_testdir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(installed_testdir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_installed_testDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_installed_test_DATA)'; test -n "$(installed_testdir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(installed_testdir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) $(check_LTLIBRARIES) $(check_SCRIPTS) $(check_DATA) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) $(check_SCRIPTS) $(check_DATA) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) \ + $(check_SCRIPTS) $(check_DATA) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(installed_testdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-installed_testLTLIBRARIES clean-installed_testPROGRAMS \ + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo + -rm -f ./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-installed_testLTLIBRARIES \ + install-installed_testPROGRAMS install-installed_testSCRIPTS \ + install-installed_test_metaDATA \ + install-nobase_installed_testDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo + -rm -f ./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-installed_testLTLIBRARIES \ + uninstall-installed_testPROGRAMS \ + uninstall-installed_testSCRIPTS \ + uninstall-installed_test_metaDATA \ + uninstall-nobase_installed_testDATA + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am check-local clean clean-checkLTLIBRARIES \ + clean-checkPROGRAMS clean-generic \ + clean-installed_testLTLIBRARIES clean-installed_testPROGRAMS \ + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-installed_testLTLIBRARIES \ + install-installed_testPROGRAMS install-installed_testSCRIPTS \ + install-installed_test_metaDATA install-man \ + install-nobase_installed_testDATA install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-installed_testLTLIBRARIES \ + uninstall-installed_testPROGRAMS \ + uninstall-installed_testSCRIPTS \ + uninstall-installed_test_metaDATA \ + uninstall-nobase_installed_testDATA + +.PRECIOUS: Makefile + + +# test-nonrecursive: run tests only in cwd +@OS_UNIX_TRUE@test-nonrecursive: ${TEST_PROGS} +@OS_UNIX_TRUE@ @test -z "${TEST_PROGS}" || G_TEST_SRCDIR="$(abs_srcdir)" G_TEST_BUILDDIR="$(abs_builddir)" G_DEBUG=gc-friendly MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${GTESTER} --verbose ${TEST_PROGS} +@OS_UNIX_FALSE@test-nonrecursive: + +.PHONY: test-nonrecursive + +.PHONY: lcov genlcov lcov-clean +# use recursive makes in order to ignore errors during check +lcov: + -$(MAKE) $(AM_MAKEFLAGS) -k check + $(MAKE) $(AM_MAKEFLAGS) genlcov + +# we have to massage the lcov.info file slightly to hide the effect of libtool +# placing the objects files in the .libs/ directory separate from the *.c +# we also have to delete tests/.libs/libmoduletestplugin_*.gcda +genlcov: + $(AM_V_GEN) rm -f $(top_builddir)/tests/.libs/libmoduletestplugin_*.gcda; \ + $(LTP) --quiet --directory $(top_builddir) --capture --output-file glib-lcov.info --test-name GLIB_PERF --no-checksum --compat-libtool --ignore-errors source; \ + $(LTP) --quiet --output-file glib-lcov.info --remove glib-lcov.info docs/reference/\* /tmp/\* gio/tests/gdbus-object-manager-example/\* ; \ + LANG=C $(LTP_GENHTML) --quiet --prefix $(top_builddir) --output-directory glib-lcov --title "GLib Code Coverage" --legend --frames --show-details glib-lcov.info --ignore-errors source + @echo "file://$(abs_top_builddir)/glib-lcov/index.html" + +lcov-clean: + if test -n "$(LTP)"; then \ + $(LTP) --quiet --directory $(top_builddir) -z; \ + fi + +# run tests in cwd as part of make check +check-local: test-nonrecursive + +@ENABLE_INSTALLED_TESTS_TRUE@%.test: %$(EXEEXT) Makefile +@ENABLE_INSTALLED_TESTS_TRUE@ $(AM_V_GEN) (echo '[Test]' > $@.tmp; \ +@ENABLE_INSTALLED_TESTS_TRUE@ echo 'Type=session' >> $@.tmp; \ +@ENABLE_INSTALLED_TESTS_TRUE@ echo 'Exec=$(installed_testdir)/$(notdir $<)' >> $@.tmp; \ +@ENABLE_INSTALLED_TESTS_TRUE@ mv $@.tmp $@) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: --- devel/glib20/files/kqueue_fnm.c (nonexistent) +++ devel/glib20/files/kqueue_fnm.c (working copy) @@ -0,0 +1,1083 @@ +/*- + * Copyright (c) 2016 - 2018 Rozhuk Ivan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Rozhuk Ivan + * + */ + +#include +#include +#include +#include +#include +#include +#include /* open, fcntl */ + +#include +#include /* malloc, exit */ +#include /* close, write, sysconf */ +#include /* bcopy, bzero, memcpy, memmove, memset, strerror... */ +#include /* opendir, readdir */ +#include +#include + +#include "kqueue_fnm.h" + + +/* Preallocate items count. */ +#ifndef FILES_ALLOC_BLK_SIZE +# define FILES_ALLOC_BLK_SIZE 32 +#endif + + +typedef struct readdir_context_s { + int fd; + uint8_t *buf; + size_t buf_size; + size_t buf_used; + size_t buf_pos; +} readdir_ctx_t, *readdir_ctx_p; + + +typedef struct file_info_s { /* Directory file. */ + int fd; /* For notify kqueue(). */ + struct dirent de; /* d_reclen used for action. */ + struct stat sb; +} file_info_t, *file_info_p; + + +typedef struct kq_file_nmon_obj_s { + int fd; /* For notify kqueue(). */ + int is_dir; + int is_local; /* Is file system local. */ + struct stat sb; + char path[(PATH_MAX + 2)]; + size_t path_size; + size_t name_offset; /* Parent path size. */ + uint32_t rate_lim_cur_interval; /* From rate_limit_time_init to rate_limit_time_max. 0 disabled. */ + size_t rate_lim_ev_cnt; /* Events count then rate_lim_cur_interval != 0 since last report. */ + sbintime_t rate_lim_ev_last; /* Last event time. */ + void *udata; + kq_fnm_p kfnm; + /* For dir. */ + file_info_p files; + volatile size_t files_count; + size_t files_allocated; +} kq_fnmo_t; + + +typedef struct kq_file_nonify_monitor_s { + int fd; /* kqueue() fd. */ + int pfd[2]; /* pipe queue specific. */ + kfnm_event_handler_cb cb_func; /* Callback on dir/file change. */ + kq_file_mon_settings_t s; + sbintime_t rate_lim_time_init; /* rate_limit_time_init */ + pthread_t tid; +} kq_fnm_t; + + +typedef void (*kq_msg_cb)(void *arg); + +typedef struct kq_file_mon_msg_pkt_s { + size_t magic; + kq_msg_cb msg_cb; + void *arg; + size_t chk_sum; +} kq_fnm_msg_pkt_t, *kq_fnm_msg_pkt_p; + +#define KF_MSG_PKT_MAGIC 0xffddaa00 + + +#ifndef O_NOATIME +# define O_NOATIME 0 +#endif +#ifndef O_EVTONLY +# define O_EVTONLY O_RDONLY +#endif +#define OPEN_FILE_FLAGS (O_EVTONLY | O_NONBLOCK | O_NOFOLLOW | O_NOATIME | O_CLOEXEC) + +#define EVFILT_VNODE_SUB_FLAGS (NOTE_WRITE | \ + NOTE_EXTEND | \ + NOTE_ATTRIB | \ + NOTE_LINK | \ + NOTE_CLOSE_WRITE) + +#define EVFILT_VNODE_FLAGS_ALL (NOTE_DELETE | \ + EVFILT_VNODE_SUB_FLAGS | \ + NOTE_RENAME | \ + NOTE_REVOKE) + +#ifndef _GENERIC_DIRSIZ +# define _GENERIC_DIRSIZ(__de) MIN((__de)->d_reclen, sizeof(struct dirent)) +#endif + +#define IS_NAME_DOTS(__name) ('.' == (__name)[0] && \ + ('\0' == (__name)[1] || \ + ('.' == (__name)[1] && '\0' == (__name)[2]))) +#define IS_DE_NAME_EQ(__de1, __de2) (0 == mem_cmpn((__de1)->d_name, \ + (__de1)->d_namlen, \ + (__de2)->d_name, \ + (__de2)->d_namlen)) +#define zalloc(__size) calloc(1, (__size)) + +#if (!defined(HAVE_REALLOCARRAY) && (!defined(__FreeBSD_version) || __FreeBSD_version < 1100000)) +# define reallocarray(__mem, __size, __count) realloc((__mem), ((__size) * (__count))) +#endif + +/* To not depend from compiller version. */ +#define MSTOSBT(__ms) ((sbintime_t)((((int64_t)(__ms)) * (int64_t)(((uint64_t)1 << 63) / 500) >> 32))) + +#ifndef CLOCK_MONOTONIC_FAST +# define CLOCK_MONOTONIC_FAST CLOCK_MONOTONIC +#endif + + +void *kq_fnm_proccess_events_proc(void *data); + +static inline int +mem_cmpn(const void *buf1, const size_t buf1_size, + const void *buf2, const size_t buf2_size) { + + if (buf1_size != buf2_size) + return (((buf1_size > buf2_size) ? 127 : -127)); + if (0 == buf1_size || buf1 == buf2) + return (0); + if (NULL == buf1) + return (-127); + if (NULL == buf2) + return (127); + return (memcmp(buf1, buf2, buf1_size)); +} + +static int +realloc_items(void **items, const size_t item_size, + size_t *allocated, const size_t alloc_blk_cnt, const size_t count) { + size_t allocated_prev, allocated_new; + uint8_t *items_new; + + if (NULL == items || 0 == item_size || NULL == allocated || + 0 == alloc_blk_cnt) + return (EINVAL); + allocated_prev = (*allocated); + if (NULL != (*items) && + allocated_prev > count && + allocated_prev <= (count + alloc_blk_cnt)) + return (0); + allocated_new = (((count / alloc_blk_cnt) + 1) * alloc_blk_cnt); + items_new = (uint8_t*)reallocarray((*items), item_size, allocated_new); + if (NULL == items_new) /* Realloc fail! */ + return (ENOMEM); + + if (allocated_new > allocated_prev) { /* Init new mem. */ + memset((items_new + (allocated_prev * item_size)), 0x00, + ((allocated_new - allocated_prev) * item_size)); + } + (*items) = items_new; + (*allocated) = allocated_new; + + return (0); +} + + +static int +readdir_start(int fd, struct stat *sb, size_t exp_count, readdir_ctx_p rdd) { + size_t buf_size; + + if (-1 == fd || NULL == sb || NULL == rdd) + return (EINVAL); + if (-1 == lseek(fd, 0, SEEK_SET)) + return (errno); + /* Calculate buf size for getdents(). */ + buf_size = MAX((size_t)sb->st_size, (exp_count * sizeof(struct dirent))); + if (0 == buf_size) { + buf_size = (16 * PAGE_SIZE); + } + /* Make buf size well aligned. */ + if (0 != sb->st_blksize) { + if (powerof2(sb->st_blksize)) { + buf_size = roundup2(buf_size, sb->st_blksize); + } else { + buf_size = roundup(buf_size, sb->st_blksize); + } + } else { + buf_size = round_page(buf_size); + } + /* Init. */ + memset(rdd, 0x00, sizeof(readdir_ctx_t)); + rdd->buf = malloc(buf_size); + if (NULL == rdd->buf) + return (ENOMEM); + rdd->buf_size = buf_size; + rdd->fd = fd; + + return (0); +} + +static void +readdir_free(readdir_ctx_p rdd) { + + if (NULL == rdd || NULL == rdd->buf) + return; + free(rdd->buf); + memset(rdd, 0x00, sizeof(readdir_ctx_t)); +} + +static int +readdir_next(readdir_ctx_p rdd, struct dirent *de) { + int error = 0, ios; + uint8_t *ptr; + + if (NULL == rdd || NULL == rdd->buf || NULL == de) + return (EINVAL); + + for (;;) { + if (rdd->buf_used <= rdd->buf_pos) { + /* Called once if buf size calculated ok. */ + ios = getdents(rdd->fd, (char*)rdd->buf, (int)rdd->buf_size); + if (-1 == ios) { + error = errno; + break; + } + if (0 == ios) { + error = ESPIPE; /* EOF. */ + break; + } + rdd->buf_used = (size_t)ios; + rdd->buf_pos = 0; + } + /* Keep data aligned. */ + ptr = (rdd->buf + rdd->buf_pos); + memcpy(de, ptr, (sizeof(struct dirent) - sizeof(de->d_name))); + if (0 == de->d_reclen) { + error = ESPIPE; /* EOF. */ + break; + } + rdd->buf_pos += de->d_reclen; +#ifdef DT_WHT + if (DT_WHT == de->d_type) + continue; +#endif + memcpy(de, ptr, _GENERIC_DIRSIZ(de)); + if (!IS_NAME_DOTS(de->d_name)) + return (0); /* OK. */ + } + + /* Err or no more files. */ + readdir_free(rdd); + + return (error); +} + + +static int +file_info_find_ni(file_info_p files, size_t files_count, + file_info_p fi, size_t *idx) { + size_t i; + mode_t st_ftype; + + if (NULL == files || NULL == fi || NULL == idx) + return (0); + st_ftype = (S_IFMT & fi->sb.st_mode); + for (i = 0; i < files_count; i ++) { + if ((S_IFMT & files[i].sb.st_mode) != st_ftype) + continue; + if ((fi->sb.st_ino != files[i].sb.st_ino || + fi->de.d_fileno != files[i].de.d_fileno) && + 0 == IS_DE_NAME_EQ(&fi->de, &files[i].de)) + continue; + (*idx) = i; + return (1); + } + (*idx) = files_count; + return (0); +} + +static int +file_info_find_ino(file_info_p files, size_t files_count, + file_info_p fi, size_t *idx) { + size_t i; + mode_t st_ftype; + + if (NULL == files || NULL == fi || NULL == idx) + return (0); + st_ftype = (S_IFMT & fi->sb.st_mode); + for (i = 0; i < files_count; i ++) { + if ((S_IFMT & files[i].sb.st_mode) != st_ftype || + fi->sb.st_ino != files[i].sb.st_ino || + fi->de.d_fileno != files[i].de.d_fileno) + continue; + (*idx) = i; + return (1); + } + (*idx) = files_count; + return (0); +} + +static int +file_info_find_name(file_info_p files, size_t files_count, + file_info_p fi, size_t *idx) { + size_t i; + mode_t st_ftype; + + if (NULL == files || NULL == fi || NULL == idx) + return (0); + st_ftype = (S_IFMT & fi->sb.st_mode); + for (i = 0; i < files_count; i ++) { + if ((S_IFMT & files[i].sb.st_mode) != st_ftype || + 0 == IS_DE_NAME_EQ(&fi->de, &files[i].de)) + continue; + (*idx) = i; + return (1); + } + (*idx) = files_count; + return (0); +} + +static void +file_info_fd_close(file_info_p files, size_t files_count) { + size_t i; + + if (NULL == files || 0 == files_count) + return; + for (i = 0; i < files_count; i ++) { + if (-1 == files[i].fd) + continue; + close(files[i].fd); + files[i].fd = -1; + } +} + + +static int +is_fs_local(struct statfs *stfs, const char **local_fs, const char **non_local_fs) { + size_t i; + + if (NULL == stfs) + return (0); + if (NULL != local_fs) { + for (i = 0; NULL != local_fs[i]; i ++) { + if (0 == strncmp(stfs->f_fstypename, local_fs[i], + sizeof(stfs->f_fstypename))) + return (1); + } + } + if (0 == (MNT_LOCAL & stfs->f_flags)) + return (0); + if (NULL != non_local_fs) { + for (i = 0; NULL != non_local_fs[i]; i ++) { + if (0 == strncmp(stfs->f_fstypename, non_local_fs[i], + sizeof(stfs->f_fstypename))) + return (0); + } + } + return (1); +} + + +static void +kq_fnmo_rate_lim_stop(kq_fnmo_p fnmo) { + struct kevent kev; + + if (NULL == fnmo || -1 == fnmo->fd || 0 == fnmo->rate_lim_cur_interval) + return; + fnmo->rate_lim_cur_interval = 0; + fnmo->rate_lim_ev_cnt = 0; + EV_SET(&kev, fnmo->fd, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); + kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL); +} + +static int +kq_fnmo_rate_lim_shedule_next(kq_fnmo_p fnmo) { + u_short flags = (EV_ADD | EV_CLEAR | EV_ONESHOT); + struct kevent kev; + + if (NULL == fnmo || -1 == fnmo->fd || 0 == fnmo->kfnm->s.rate_limit_time_init) + return (EINVAL); + if (0 == fnmo->rate_lim_cur_interval) { /* First call. */ + fnmo->rate_lim_cur_interval = fnmo->kfnm->s.rate_limit_time_init; + } else { + if (fnmo->rate_lim_cur_interval == fnmo->kfnm->s.rate_limit_time_max) + return (0); /* No need to modify timer. */ + /* Increase rate limit interval. */ + fnmo->rate_lim_cur_interval *= fnmo->kfnm->s.rate_limit_time_mul; + } + if (fnmo->rate_lim_cur_interval >= fnmo->kfnm->s.rate_limit_time_max) { + /* Check upper limit and shedule periodic timer with upper rate limit time. */ + flags &= ~EV_ONESHOT; + fnmo->rate_lim_cur_interval = fnmo->kfnm->s.rate_limit_time_max; + } + EV_SET(&kev, fnmo->fd, EVFILT_TIMER, flags, + NOTE_MSECONDS, fnmo->rate_lim_cur_interval, fnmo); + if (-1 == kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL)) { + fnmo->rate_lim_cur_interval = 0; + return (errno); + } + if (0 != (EV_ERROR & kev.flags)) { + fnmo->rate_lim_cur_interval = 0; + return ((int)kev.data); + } + return (0); +} + +/* Return: + * 0 for events that not handled + * 1 for handled = rate limited + * -1 on error. + */ +static int +kq_fnmo_rate_lim_check(kq_fnmo_p fnmo) { + sbintime_t sbt, sbt_now; + struct timespec ts; + + if (NULL == fnmo) + return (-1); + if (-1 == fnmo->fd || + 0 == fnmo->kfnm->s.rate_limit_time_init) + return (0); + if (0 != fnmo->rate_lim_cur_interval) { + fnmo->rate_lim_ev_cnt ++; /* Count event, timer is active. */ + return (1); + } + + /* Do we need to enable rate limit? */ + if (0 != clock_gettime(CLOCK_MONOTONIC_FAST, &ts)) + return (-1); + sbt_now = tstosbt(ts); + sbt = (fnmo->rate_lim_ev_last + fnmo->kfnm->rate_lim_time_init); + fnmo->rate_lim_ev_last = sbt_now; + if (sbt < sbt_now) /* Events rate to low. */ + return (0); + /* Try to enable rate limit. */ + if (0 != kq_fnmo_rate_lim_shedule_next(fnmo)) + return (-1); + /* Ok. */ + fnmo->rate_lim_ev_cnt ++; + + return (1); +} + +static void +kq_fnmo_clean(kq_fnmo_p fnmo) { + + if (NULL == fnmo) + return; + if (-1 != fnmo->fd) { + kq_fnmo_rate_lim_stop(fnmo); + close(fnmo->fd); + fnmo->fd = -1; + } + if (0 != fnmo->is_local) { /* Stop monitoring files/dirs. */ + file_info_fd_close(fnmo->files, fnmo->files_count); + } + free(fnmo->files); + fnmo->files = NULL; + fnmo->files_count = 0; + fnmo->files_allocated = 0; +} + +static void +kq_fnmo_free(void *arg) { + kq_fnmo_p fnmo = arg; + + if (NULL == fnmo) + return; + kq_fnmo_clean(fnmo); + free(fnmo); +} + +static kq_fnmo_p +kq_fnmo_alloc(kq_fnm_p kfnm, const char *path, void *udata) { + kq_fnmo_p fnmo; + + if (NULL == kfnm || NULL == path) + return (NULL); + fnmo = zalloc(sizeof(kq_fnmo_t)); + if (NULL == fnmo) + return (NULL); + /* Remember args. */ + fnmo->path_size = strlcpy(fnmo->path, path, PATH_MAX); + fnmo->name_offset = fnmo->path_size; + fnmo->udata = udata; + fnmo->kfnm = kfnm; + + return (fnmo); +} + +static int +kq_fnmo_readdir(kq_fnmo_p fnmo, size_t exp_count) { + int error; + struct dirent *de; + file_info_p tmfi; + readdir_ctx_t rdd; + + if (NULL == fnmo || 0 == fnmo->is_dir) + return (EINVAL); + + free(fnmo->files); + fnmo->files = NULL; + fnmo->files_count = 0; + fnmo->files_allocated = 0; + /* Pre allocate. */ + if (0 != realloc_items((void**)&fnmo->files, + sizeof(file_info_t), &fnmo->files_allocated, + FILES_ALLOC_BLK_SIZE, (exp_count + 1))) + return (ENOMEM); + + error = readdir_start(fnmo->fd, &fnmo->sb, exp_count, &rdd); + if (0 != error) + return (error); + for (;;) { + if (0 != realloc_items((void**)&fnmo->files, + sizeof(file_info_t), &fnmo->files_allocated, + FILES_ALLOC_BLK_SIZE, fnmo->files_count)) { + free(fnmo->files); + fnmo->files = NULL; + fnmo->files_count = 0; + fnmo->files_allocated = 0; + readdir_free(&rdd); + return (ENOMEM); + } + de = &fnmo->files[fnmo->files_count].de; /* Use short name. */ + /* Get file name from folder. */ + if (0 != readdir_next(&rdd, de)) + break; + /* Get file attrs. */ + if (0 != fstatat(fnmo->fd, de->d_name, + &fnmo->files[fnmo->files_count].sb, + AT_SYMLINK_NOFOLLOW)) { + memset(&fnmo->files[fnmo->files_count].sb, 0x00, + sizeof(struct stat)); + } + fnmo->files[fnmo->files_count].fd = -1; + fnmo->files_count ++; + } + /* Mem compact. */ + tmfi = reallocarray(fnmo->files, sizeof(file_info_t), (fnmo->files_count + 1)); + if (NULL != tmfi) { /* realloc ok. */ + fnmo->files = tmfi; + fnmo->files_allocated = (fnmo->files_count + 1); + } + + readdir_free(&rdd); + + return (0); /* OK. */ +} + + +static void +kq_fnmo_fi_start(kq_fnmo_p fnmo, file_info_p fi) { + struct kevent kev; + + if (NULL == fnmo || NULL == fi) + return; + fi->fd = openat(fnmo->fd, fi->de.d_name, OPEN_FILE_FLAGS); + if (-1 == fi->fd) + return; + EV_SET(&kev, fi->fd, EVFILT_VNODE, + (EV_ADD | EV_CLEAR), + EVFILT_VNODE_SUB_FLAGS, 0, fnmo); + kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL); +} + +static int +kq_fnmo_is_fi_monitored(kq_fnmo_p fnmo, file_info_p fi) { + + if (NULL == fnmo) + return (0); + if (0 == fnmo->is_local || + (0 != fnmo->kfnm->s.max_dir_files && + fnmo->kfnm->s.max_dir_files < fnmo->files_count)) + return (0); + if (NULL != fi && + 0 == fnmo->kfnm->s.mon_local_subdirs && + S_ISDIR(fi->sb.st_mode)) + return (0); + return (1); +} + +static void +kq_fnmo_init(void *arg) { + kq_fnmo_p fnmo = arg; + size_t i; + struct statfs stfs; + struct kevent kev; + + if (NULL == fnmo) + return; + fnmo->fd = open(fnmo->path, OPEN_FILE_FLAGS); + if (-1 == fnmo->fd) + return; + if (0 != fstat(fnmo->fd, &fnmo->sb)) + goto err_out; + + /* Get parent folder name. */ + if (S_ISDIR(fnmo->sb.st_mode)) { + fnmo->is_dir = 1; + /* Be sure that folder contain trailing '/'. */ + if ('/' != fnmo->path[(fnmo->path_size - 1)]) { + fnmo->path[fnmo->path_size] = '/'; + fnmo->path_size ++; + fnmo->path[fnmo->path_size] = 0; + } + /* Skip last '/' for parent dir search. */ + fnmo->name_offset = (fnmo->path_size - 1); + } + + /* Is file system local? */ + if (0 != fnmo->is_dir && + 0 != fnmo->kfnm->s.mon_local_subfiles && + 0 == fstatfs(fnmo->fd, &stfs)) { + fnmo->is_local = is_fs_local(&stfs, fnmo->kfnm->s.local_fs, + fnmo->kfnm->s.non_local_fs); + } + + /* Find parent dir path size. */ + while (0 < fnmo->name_offset && '/' != fnmo->path[(fnmo->name_offset - 1)]) { + fnmo->name_offset --; + } + + /* Dir special processing. */ + if (0 != fnmo->is_dir) { + /* Read and remember dir content. */ + if (0 != kq_fnmo_readdir(fnmo, 0)) + goto err_out; + } + /* Add to kqueue. */ + EV_SET(&kev, fnmo->fd, EVFILT_VNODE, (EV_ADD | EV_CLEAR), + EVFILT_VNODE_FLAGS_ALL, 0, fnmo); + if (-1 == kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL) || + 0 != (EV_ERROR & kev.flags)) + goto err_out; + /* Add monitor sub files/dirs, ignory errors. */ + /* Check twice for performance reason. */ + if (0 != kq_fnmo_is_fi_monitored(fnmo, NULL)) { + for (i = 0; i < fnmo->files_count; i ++) { + if (0 != kq_fnmo_is_fi_monitored(fnmo, &fnmo->files[i])) { + kq_fnmo_fi_start(fnmo, &fnmo->files[i]); + } + } + } + + return; /* OK. */ + +err_out: + kq_fnmo_clean(fnmo); +} + +static void +kq_handle_changes(kq_fnm_p kfnm, kq_fnmo_p fnmo) { + size_t i, k, files_count; + file_info_p files; + + if (NULL == kfnm || NULL == fnmo) + return; + if (0 != fstat(fnmo->fd, &fnmo->sb) || + 0 == fnmo->sb.st_nlink) { + kq_fnmo_clean(fnmo); + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_DELETED, + fnmo->path, "", NULL); + return; + } + if (0 == fnmo->is_dir) { + fnmo->path[fnmo->name_offset] = 0; + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_CHANGED, + fnmo->path, (fnmo->path + fnmo->name_offset), NULL); + fnmo->path[fnmo->name_offset] = '/'; + return; + } + + /* Dir processing. */ + + /* Save prev. */ + files = fnmo->files; + files_count = fnmo->files_count; + fnmo->files = NULL; + fnmo->files_count = 0; + /* Update dir. */ + if (0 != kq_fnmo_readdir(fnmo, files_count)) { + /* Restore prev state on fail. */ + fnmo->files = files; + fnmo->files_count = files_count; + return; + } + /* Notify removed first. */ + for (i = 0; i < files_count; i ++) { + if (0 != file_info_find_ni(fnmo->files, fnmo->files_count, &files[i], &k)) /* Deleted? */ + continue; + if (-1 != files[i].fd) { + close(files[i].fd); + files[i].fd = -1; + } + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_DELETED, + fnmo->path, files[i].de.d_name, NULL); + } + /* Notify. */ + for (i = 0; i < fnmo->files_count; i ++) { + /* Is new file/folder? */ + if (0 == file_info_find_ino(files, files_count, &fnmo->files[i], &k) && + 0 == file_info_find_name(files, files_count, &fnmo->files[i], &k)) { /* Add new. */ + /* Add monitor sub files/dirs, ignory errors. */ + if (0 != kq_fnmo_is_fi_monitored(fnmo, &fnmo->files[i])) { + kq_fnmo_fi_start(fnmo, &fnmo->files[i]); + } + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_CREATED, + fnmo->path, fnmo->files[i].de.d_name, NULL); + continue; + } + /* Keep file fd. */ + fnmo->files[i].fd = files[k].fd; + files[k].fd = -1; + /* Is renamed? */ + if (0 == IS_DE_NAME_EQ(&files[k].de, &fnmo->files[i].de)) { + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_RENAMED, + fnmo->path, files[k].de.d_name, fnmo->files[i].de.d_name); + continue; + } + /* Is modified? */ + if (0 != memcmp(&fnmo->files[i].sb, &files[k].sb, sizeof(struct stat))) { + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_CHANGED, + fnmo->path, fnmo->files[i].de.d_name, NULL); + continue; + } + /* Not changed. */ + } + + /* Prevent FD leak die to race conditions. + * All fd must be -1, check this while debuging. + */ + file_info_fd_close(files, files_count); + free(files); +} + +static void +kq_handle_rename(kq_fnm_p kfnm, kq_fnmo_p fnmo) { + int up_dir_fd, found = 0; + readdir_ctx_t rdd; + struct dirent de; + struct stat sb; + char old_filename[(MAXNAMLEN + 2)]; + size_t old_filename_size; + + if (NULL == kfnm || NULL == fnmo) + return; + if (0 != fstat(fnmo->fd, &fnmo->sb) || + 0 == fnmo->sb.st_nlink) { +notify_removed: + kq_fnmo_clean(fnmo); + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_DELETED, + fnmo->path, "", NULL); + return; + } + /* Save old file name. */ + old_filename_size = (fnmo->path_size - fnmo->name_offset - (size_t)fnmo->is_dir); + memcpy(old_filename, + (fnmo->path + fnmo->name_offset), + old_filename_size); + old_filename[old_filename_size] = 0; + + /* Get parent folder name. */ + fnmo->path[fnmo->name_offset] = 0; + /* Try to open. */ + up_dir_fd = open(fnmo->path, (OPEN_FILE_FLAGS | O_DIRECTORY)); + /* Restore '/' after parent folder. */ + fnmo->path[fnmo->name_offset] = '/'; + if (-1 == up_dir_fd || + 0 != fstat(up_dir_fd, &sb) || + 0 != readdir_start(up_dir_fd, &sb, 0, &rdd)) { + close(up_dir_fd); + return; + } + /* Find new name by inode. */ + while (0 == readdir_next(&rdd, &de)) { + if (0 == fstatat(up_dir_fd, de.d_name, &sb, AT_SYMLINK_NOFOLLOW) && + 0 == memcmp(&fnmo->sb, &sb, sizeof(struct stat))) { + found ++; + break; + } + } + close(up_dir_fd); + if (0 == found) + goto notify_removed; /* Not found. */ + /* Update name. */ + if (PATH_MAX <= (fnmo->name_offset + de.d_namlen)) + return; /* Too long. */ + memcpy((fnmo->path + fnmo->name_offset), de.d_name, de.d_namlen); + fnmo->path_size = (fnmo->name_offset + de.d_namlen); + /* Add last '/' for dir. */ + fnmo->path[fnmo->path_size] = '/'; + fnmo->path_size += (size_t)fnmo->is_dir; + fnmo->path[fnmo->path_size] = 0; + /* Notify. */ + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_RENAMED, + fnmo->path, old_filename, de.d_name); +} + + +static void +kq_fnm_delay_call_process(kq_fnm_p kfnm, kq_msg_cb forced_msg_cb) { + ssize_t ios; + kq_fnm_msg_pkt_t msg; + + for (;;) { + ios = read(kfnm->pfd[0], &msg, sizeof(msg)); + if (0 >= ios) + return; + if (sizeof(msg) != ios || + KF_MSG_PKT_MAGIC != msg.magic || + (((size_t)msg.msg_cb) ^ ((size_t)msg.arg)) != msg.chk_sum) + continue; + if (NULL != forced_msg_cb) { + forced_msg_cb(msg.arg); + continue; + } + if (NULL == msg.msg_cb) + continue; + msg.msg_cb(msg.arg); + } +} + +static int +kq_fnm_delay_call(kq_fnm_p kfnm, kq_msg_cb msg_cb, + void *arg) { + kq_fnm_msg_pkt_t msg; + + if (NULL == kfnm || NULL == arg) + return (EINVAL); + msg.magic = KF_MSG_PKT_MAGIC; + msg.msg_cb = msg_cb; + msg.arg = arg; + msg.chk_sum = (((size_t)msg.msg_cb) ^ ((size_t)msg.arg)); + if (sizeof(msg) == write(kfnm->pfd[1], &msg, sizeof(msg))) + return (0); + return (errno); +} + + +static void +kq_fnm_free_cb(void *arg) { + kq_fnm_p kfnm = arg; + + if (NULL == kfnm) + return; + close(kfnm->fd); + kfnm->fd = -1; +} +void +kq_fnm_free(kq_fnm_p kfnm) { + + if (NULL == kfnm) + return; + kq_fnm_delay_call(kfnm, kq_fnm_free_cb, kfnm); + pthread_join(kfnm->tid, NULL); + /* Free all in delay calls queue. */ + close(kfnm->pfd[1]); + kq_fnm_delay_call_process(kfnm, kq_fnmo_free); + close(kfnm->pfd[0]); + free(kfnm); +} + +kq_fnm_p +kq_fnm_create(kq_file_mon_settings_p s, kfnm_event_handler_cb cb_func) { + kq_fnm_p kfnm; + struct kevent kev; + + if (NULL == s || NULL == cb_func) + return (NULL); + kfnm = zalloc(sizeof(kq_fnm_t)); + if (NULL == kfnm) + return (NULL); + kfnm->fd = kqueue(); + if (-1 == kfnm->fd) + goto err_out; + if (-1 == pipe2(kfnm->pfd, O_NONBLOCK)) + goto err_out; + kfnm->cb_func = cb_func; + memcpy(&kfnm->s, s, sizeof(kq_file_mon_settings_t)); + if (kfnm->s.rate_limit_time_init >= kfnm->s.rate_limit_time_max) { + kfnm->s.rate_limit_time_max = kfnm->s.rate_limit_time_init; + } + if (0 == kfnm->s.rate_limit_time_mul) { + kfnm->s.rate_limit_time_mul ++; + } + kfnm->rate_lim_time_init = MSTOSBT(kfnm->s.rate_limit_time_init); + + EV_SET(&kev, kfnm->pfd[0], EVFILT_READ, EV_ADD, 0, 0, NULL); + if (-1 == kevent(kfnm->fd, &kev, 1, NULL, 0, NULL) || + 0 != (EV_ERROR & kev.flags)) + goto err_out; + if (0 != pthread_create(&kfnm->tid, NULL, + kq_fnm_proccess_events_proc, kfnm)) + goto err_out; + + return (kfnm); + +err_out: + kq_fnm_free(kfnm); + return (NULL); +} + +kq_fnmo_p +kq_fnm_add(kq_fnm_p kfnm, const char *path, void *udata) { + int error; + kq_fnmo_p fnmo; + + if (NULL == kfnm || NULL == path) + return (NULL); + fnmo = kq_fnmo_alloc(kfnm, path, udata); + if (NULL == fnmo) + return (NULL); + /* Shedule delay call to init. */ + error = kq_fnm_delay_call(kfnm, kq_fnmo_init, fnmo); + if (0 != error) { /* Error, do no directly init to avoid freezes. */ + kq_fnmo_free(fnmo); + return (NULL); + } + return (fnmo); +} + +void +kq_fnm_del(kq_fnm_p kfnm, kq_fnmo_p fnmo) { + int error; + + if (NULL == kfnm || NULL == fnmo) + return; + /* Cancel notifications. */ + kq_fnmo_rate_lim_stop(fnmo); + close(fnmo->fd); + fnmo->fd = -1; + /* Shedule delay call to free. */ + error = kq_fnm_delay_call(kfnm, kq_fnmo_free, fnmo); + if (0 == error) + return; + /* Error, free directly. */ + kq_fnmo_free(fnmo); +} + + +static void +kq_fnm_proccess_event(kq_fnm_p kfnm, struct kevent *kev) { + kq_fnmo_p fnmo; + file_info_p fi; + size_t i; + int is_rate_lim_checked = 0; + struct stat sb; + + if (NULL == kfnm || NULL == kev) + return; + + /* Handle delay calls. */ + if (kev->ident == (uintptr_t)kfnm->pfd[0]) { + if (kev->filter == EVFILT_READ) { + kq_fnm_delay_call_process(kfnm, NULL); + } + return; + } + + if (0 == kev->udata) + return; /* No associated data, skip. */ + fnmo = (kq_fnmo_p)kev->udata; + + /* FS delayed notifications. */ + if (EVFILT_TIMER == kev->filter) { + if (0 == fnmo->rate_lim_ev_cnt) { + /* No delayed events, disable rate limit polling. */ + kq_fnmo_rate_lim_stop(fnmo); + return; + } + fnmo->rate_lim_ev_cnt = 0; /* Reset counter. */ + kq_fnmo_rate_lim_shedule_next(fnmo); + kq_handle_changes(kfnm, fnmo); + return; + } + + /* FS notifications. */ + if (EVFILT_VNODE != kev->filter) + return; /* Unknown event, skip. */ + /* Subdir/file */ + if (kev->ident != (uintptr_t)fnmo->fd) { + /* Is files changes rate limited? */ + if (1 == kq_fnmo_rate_lim_check(fnmo)) + return; + is_rate_lim_checked ++; + /* Try to find file and check it, without call kq_handle_changes(). */ + fi = NULL; + for (i = 0; i < fnmo->files_count; i ++) { + if (kev->ident != (uintptr_t)fnmo->files[i].fd) + continue; + fi = &fnmo->files[i]; + break; + } + if (NULL != fi) { + /* Get file attrs. */ + if (0 != fstat(fi->fd, &sb)) { + memset(&sb, 0x00, sizeof(struct stat)); + } + /* Is modified? */ + if (0 != memcmp(&fi->sb, &sb, sizeof(struct stat))) { + memcpy(&fi->sb, &sb, sizeof(struct stat)); + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_CHANGED, + fnmo->path, fi->de.d_name, NULL); + return; + } + } + /* fd not found or changes not found, rescan dir. */ + kev->fflags = NOTE_WRITE; + } + /* Monitored object. */ + /* All flags from EVFILT_VNODE_FLAGS_ALL must be handled here. */ + if (EV_ERROR & kev->flags) { + kev->fflags |= NOTE_REVOKE; /* Treat error as unmount. */ + } + if (NOTE_RENAME & kev->fflags) { + kq_handle_rename(kfnm, fnmo); + } + if ((NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_CLOSE_WRITE) & kev->fflags) { + /* Only count changes, do not prevent NOTE_DELETE event handling. */ + if (0 == is_rate_lim_checked && + 1 != kq_fnmo_rate_lim_check(fnmo)) { + kq_handle_changes(kfnm, fnmo); + } + } + if ((NOTE_DELETE | NOTE_REVOKE) & kev->fflags) { + /* No report about childs. */ + kq_fnmo_clean(fnmo); + kfnm->cb_func(kfnm, fnmo, fnmo->udata, KF_EVENT_DELETED, + fnmo->path, "", NULL); + } +} + +void * +kq_fnm_proccess_events_proc(void *data) { + struct kevent kev; + kq_fnm_p kfnm = data; + + if (NULL == kfnm) + return (NULL); + /* Get and proccess events, no wait. */ + while (0 < kevent(kfnm->fd, NULL, 0, &kev, 1, NULL)) { + kq_fnm_proccess_event(kfnm, &kev); + } + return (NULL); +} --- devel/glib20/files/kqueue_fnm.h (nonexistent) +++ devel/glib20/files/kqueue_fnm.h (working copy) @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2016 - 2018 Rozhuk Ivan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Rozhuk Ivan + * + */ + +#ifndef __KQUEUE_FILE_NOTIFY_MONITOR_H__ +#define __KQUEUE_FILE_NOTIFY_MONITOR_H__ + +#include +#include +#include + + +typedef struct kq_file_nonify_monitor_s *kq_fnm_p; +typedef struct kq_file_nmon_obj_s *kq_fnmo_p; + +typedef void (*kfnm_event_handler_cb)(kq_fnm_p kfnm, + kq_fnmo_p fnmo, void *udata, + uint32_t event, + const char *base, + const char *filename, + const char *new_filename); +#define KF_EVENT_NOT_CHANGED 0 /* Internal use. */ +#define KF_EVENT_CREATED 1 +#define KF_EVENT_DELETED 2 +#define KF_EVENT_RENAMED 3 +#define KF_EVENT_CHANGED 4 + + +typedef struct kq_file_nonify_mon_settings_s { + uint32_t rate_limit_time_init; /* Fire events for dir min interval, mseconds. */ + uint32_t rate_limit_time_max; /* Fire events for dir max interval, mseconds. */ + uint32_t rate_limit_time_mul; /* Fire events time increment, mseconds. */ + size_t max_dir_files; /* If dir contain more than n files - do not mon files changes. */ + int mon_local_subfiles; /* Enable monitoring files changes on local file systems. */ + int mon_local_subdirs; /* Also mon for subdirs changes . */ + const char **local_fs; /* NULL terminated fs names list that threat as local. Keep utill kq_fnm_free() return. */ + const char **non_local_fs; /* NULL terminated fs names list that threat as not local. Keep utill kq_fnm_free() return. */ +} kq_file_mon_settings_t, *kq_file_mon_settings_p; + +kq_fnm_p kq_fnm_create(kq_file_mon_settings_p s, + kfnm_event_handler_cb cb_func); +void kq_fnm_free(kq_fnm_p kfnm); + +kq_fnmo_p kq_fnm_add(kq_fnm_p kfnm, + const char *path, void *udata); +void kq_fnm_del(kq_fnm_p kfnm, kq_fnmo_p fnmo); + + +#endif /* __KQUEUE_FILE_NOTIFY_MONITOR_H__ */