View | Details | Raw Unified | Return to bug 214338 | Differences between
and this patch

Collapse All | Expand All

(-)devel/glib20/Makefile (-2 / +16 lines)
Lines 49-59 Link Here
49
		glib-compile-resources.1 gresource.1 gdbus-codegen.1
49
		glib-compile-resources.1 gresource.1 gdbus-codegen.1
50
gobject_MAN=	glib-genmarshal.1 glib-mkenums.1 gobject-query.1
50
gobject_MAN=	glib-genmarshal.1 glib-mkenums.1 gobject-query.1
51
51
52
OPTIONS_DEFINE=	DEBUG MANPAGES NLS
52
OPTIONS_DEFINE=	DEBUG FAM_ALTBACKEND MANPAGES NLS
53
OPTIONS_DEFAULT=	MANPAGES
53
OPTIONS_DEFAULT=	MANPAGES
54
OPTIONS_SUB=	yes
54
OPTIONS_SUB=	yes
55
55
56
DEBUG_CONFIGURE_ON=	--enable-debug=yes
56
FAM_ALTBACKEND_DESC=		Alternate file monitor backend
57
#FAM_ALTBACKEND_USES=		autoreconf:build
58
FAM_ALTBACKEND_EXTRA_PATCHES=	${FILESDIR}/extra-patch-gio_kqueue_Makefile.am
57
59
58
MANPAGES_BUILD_DEPENDS=		docbook-xml>4.1.2:textproc/docbook-xml \
60
MANPAGES_BUILD_DEPENDS=		docbook-xml>4.1.2:textproc/docbook-xml \
59
				docbook-xsl>0:textproc/docbook-xsl
61
				docbook-xsl>0:textproc/docbook-xsl
Lines 66-71 Link Here
66
# doesn't build yet
68
# doesn't build yet
67
CONFIGURE_ARGS+=--disable-dtrace
69
CONFIGURE_ARGS+=--disable-dtrace
68
70
71
.if ${PORT_OPTIONS:MDEBUG} || defined(WITH_DEBUG)
72
CONFIGURE_ARGS+=	--enable-debug=yes
73
WITH_DEBUG?=		yes
74
.endif
75
69
.if empty(ICONV_LIB)
76
.if empty(ICONV_LIB)
70
CONFIGURE_ARGS+=	--with-libiconv=no
77
CONFIGURE_ARGS+=	--with-libiconv=no
71
.else
78
.else
Lines 94-99 Link Here
94
		s|-Werror|| ; \
101
		s|-Werror|| ; \
95
		s|#define HAVE_SYS_INOTIFY_H 1||' ${WRKSRC}/configure
102
		s|#define HAVE_SYS_INOTIFY_H 1||' ${WRKSRC}/configure
96
103
104
pre-configure-FAM_ALTBACKEND-on:
105
	@${CP} -f ${FILESDIR}/gkqueuefilemonitor.c ${WRKSRC}/gio/kqueue/gkqueuefilemonitor.c
106
	@${CP} -f ${FILESDIR}/kqueue_Makefile.in ${WRKSRC}/gio/kqueue/Makefile.in
107
	@${CP} ${FILESDIR}/kqueue_fnm.c ${WRKSRC}/gio/kqueue/kqueue_fnm.c
108
	@${CP} ${FILESDIR}/kqueue_fnm.h ${WRKSRC}/gio/kqueue/kqueue_fnm.h
109
	#@(cd ${WRKSRC} && ${AUTORECONF} -fvi)
110
97
do-build-MANPAGES-on:
111
do-build-MANPAGES-on:
98
.for m in glib gio gobject
112
.for m in glib gio gobject
99
. for file in ${${m}_MAN}
113
. for file in ${${m}_MAN}
(-)devel/glib20/files/extra-patch-gio_kqueue_Makefile.am (+26 lines)
Line 0 Link Here
1
--- gio/kqueue/Makefile.am.orig	2015-10-14 14:41:16.000000000 +0300
2
+++ gio/kqueue/Makefile.am	2016-11-06 05:08:37.646089000 +0300
3
@@ -4,21 +4,8 @@
4
 
5
 libkqueue_la_SOURCES = \
6
        gkqueuefilemonitor.c \
7
-       gkqueuefilemonitor.h \
8
-       kqueue-helper.c \
9
-       kqueue-helper.h \
10
-       kqueue-thread.c \
11
-       kqueue-thread.h \
12
-       kqueue-sub.c \
13
-       kqueue-sub.h \
14
-       kqueue-missing.c \
15
-       kqueue-missing.h \
16
-       kqueue-utils.c \
17
-       kqueue-utils.h \
18
-       kqueue-exclusions.c \
19
-       kqueue-exclusions.h \
20
-       dep-list.c \
21
-       dep-list.h \
22
+       kqueue_fnm.c \
23
+       kqueue_fnm.h \
24
        $(NULL)
25
 
26
 libkqueue_la_CFLAGS = \
(-)devel/glib20/files/gkqueuefilemonitor.c (+224 lines)
Line 0 Link Here
1
/*-
2
 * Copyright (c) 2016 - 2019 Rozhuk Ivan <rozhuk.im@gmail.com>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 *
26
 * Author: Rozhuk Ivan <rozhuk.im@gmail.com>
27
 *
28
 */
29
30
#include "config.h"
31
32
#include <glib-object.h>
33
#include <string.h>
34
#include <gio/gfilemonitor.h>
35
#include <gio/glocalfilemonitor.h>
36
#include <gio/giomodule.h>
37
#include "glib-private.h"
38
#include <glib-unix.h>
39
#include "kqueue_fnm.h"
40
41
#ifdef __clang__
42
#pragma clang diagnostic pop
43
#endif
44
45
/* Defaults. */
46
#ifndef KQUEUE_MON_RATE_LIMIT_TIME_INIT
47
#	define KQUEUE_MON_RATE_LIMIT_TIME_INIT		1000
48
#endif
49
50
#ifndef KQUEUE_MON_RATE_LIMIT_TIME_MAX
51
#	define KQUEUE_MON_RATE_LIMIT_TIME_MAX		4000
52
#endif
53
#ifndef KQUEUE_MON_RATE_LIMIT_TIME_MUL
54
#	define KQUEUE_MON_RATE_LIMIT_TIME_MUL		2
55
#endif
56
#ifndef KQUEUE_MON_MAX_DIR_FILES
57
#	define KQUEUE_MON_MAX_DIR_FILES			128
58
#endif
59
#ifndef KQUEUE_MON_LOCAL_SUBFILES
60
#	define KQUEUE_MON_LOCAL_SUBFILES		1
61
#endif
62
#ifndef KQUEUE_MON_LOCAL_SUBDIRS
63
#	define KQUEUE_MON_LOCAL_SUBDIRS			0
64
#endif
65
66
67
static GMutex			kqueue_lock;
68
static volatile kq_fnm_p	kqueue_fnm = NULL;
69
/* Exclude from file changes monitoring, watch only for dirs. */
70
static const char *non_local_fs[] = {
71
	"fusefs.sshfs",
72
	NULL
73
};
74
75
#define G_TYPE_KQUEUE_FILE_MONITOR      (g_kqueue_file_monitor_get_type())
76
#define G_KQUEUE_FILE_MONITOR(inst)     (G_TYPE_CHECK_INSTANCE_CAST((inst), \
77
					 G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor))
78
79
typedef GLocalFileMonitorClass	GKqueueFileMonitorClass;
80
81
typedef struct {
82
	GLocalFileMonitor	parent_instance;
83
	kq_fnme_p		fnme;
84
} GKqueueFileMonitor;
85
86
GType g_kqueue_file_monitor_get_type(void);
87
G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
88
       g_io_extension_point_implement(G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
89
               g_define_type_id,
90
               "kqueue",
91
               10))
92
93
94
static void
95
kqueue_event_handler(kq_fnm_p kfnm,
96
    kq_fnme_p fnme, void *udata, uint32_t event,
97
    const char *base, const char *filename, const char *new_filename) {
98
	static const uint32_t kfnm_to_glib_map[] = {
99
		0,				/* KF_EVENT_NOT_CHANGED */
100
		G_FILE_MONITOR_EVENT_CREATED,	/* KF_EVENT_CREATED */
101
		G_FILE_MONITOR_EVENT_DELETED,	/* KF_EVENT_DELETED */
102
		G_FILE_MONITOR_EVENT_RENAMED,	/* KF_EVENT_RENAMED */
103
		G_FILE_MONITOR_EVENT_CHANGED	/* KF_EVENT_CHANGED */
104
	};
105
106
	if (NULL == kfnm || NULL == filename || 0 == filename[0] ||
107
	    strchr(filename, '/') ||
108
	    KF_EVENT_CREATED > event ||
109
	    KF_EVENT_CHANGED < event)
110
		return;
111
112
	g_file_monitor_source_handle_event(udata,
113
	    kfnm_to_glib_map[event],
114
	    filename, new_filename, NULL,
115
	    g_get_monotonic_time());
116
}
117
118
static gboolean
119
g_kqueue_file_monitor_is_supported(void) {
120
	kq_file_mon_settings_t kfms;
121
122
	if (NULL != kqueue_fnm)
123
		return (TRUE);
124
	/* Init only once. */
125
	g_mutex_lock(&kqueue_lock);
126
	if (NULL != kqueue_fnm) {
127
		g_mutex_unlock(&kqueue_lock);
128
		return (TRUE); /* Initialized while wait lock. */
129
	}
130
131
	memset(&kfms, 0x00, sizeof(kq_file_mon_settings_t));
132
	kfms.rate_limit_time_init = KQUEUE_MON_RATE_LIMIT_TIME_INIT;
133
	kfms.rate_limit_time_max = KQUEUE_MON_RATE_LIMIT_TIME_MAX;
134
	kfms.rate_limit_time_mul = KQUEUE_MON_RATE_LIMIT_TIME_MUL;
135
	kfms.max_dir_files = KQUEUE_MON_MAX_DIR_FILES;
136
	kfms.mon_local_subfiles = KQUEUE_MON_LOCAL_SUBFILES;
137
	kfms.mon_local_subdirs = KQUEUE_MON_LOCAL_SUBDIRS;
138
	kfms.local_fs = NULL;
139
	kfms.non_local_fs = non_local_fs;
140
141
	kqueue_fnm = kq_fnm_create(&kfms, kqueue_event_handler);
142
	if (NULL == kqueue_fnm) {
143
		g_mutex_unlock(&kqueue_lock);
144
		return (FALSE); /* Init fail. */
145
	}
146
	g_mutex_unlock(&kqueue_lock);
147
148
	return (TRUE);
149
}
150
151
static gboolean
152
g_kqueue_file_monitor_cancel(GFileMonitor *monitor) {
153
	GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(monitor);
154
155
	kq_fnm_del(kqueue_fnm, gffm->fnme);
156
	gffm->fnme = NULL;
157
158
	return (TRUE);
159
}
160
161
static void
162
g_kqueue_file_monitor_finalize(GObject *object) {
163
	//GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(object);
164
165
	//g_mutex_lock(&kqueue_lock);
166
	//kq_fnm_free(kqueue_fnm);
167
	//kqueue_fnm = NULL;
168
	//g_mutex_unlock(&kqueue_lock);
169
	//G_OBJECT_CLASS(g_kqueue_file_monitor_parent_class)->finalize(object);
170
}
171
172
static void
173
g_kqueue_file_monitor_start(GLocalFileMonitor *local_monitor,
174
    const gchar *dirname, const gchar *basename,
175
    const gchar *filename, GFileMonitorSource *source) {
176
	GKqueueFileMonitor *gffm = G_KQUEUE_FILE_MONITOR(local_monitor);
177
178
	g_assert(NULL != kqueue_fnm);
179
	//g_source_ref((GSource*)source);
180
181
	if (NULL == filename) {
182
		filename = dirname;
183
	}
184
	gffm->fnme = kq_fnm_add(kqueue_fnm, filename, source);
185
}
186
187
static void
188
g_kqueue_file_monitor_init(GKqueueFileMonitor *monitor) {
189
190
}
191
192
static void
193
g_kqueue_file_monitor_class_init(GKqueueFileMonitorClass *class) {
194
	GObjectClass *gobject_class = G_OBJECT_CLASS(class);
195
	GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS(class);
196
197
	class->is_supported = g_kqueue_file_monitor_is_supported;
198
	class->start = g_kqueue_file_monitor_start;
199
	class->mount_notify = TRUE; /* TODO: ??? */
200
	file_monitor_class->cancel = g_kqueue_file_monitor_cancel;
201
	gobject_class->finalize = g_kqueue_file_monitor_finalize;
202
}
203
204
static void
205
g_kqueue_file_monitor_class_finalize(GKqueueFileMonitorClass *class) {
206
207
}
208
209
void
210
g_io_module_load(GIOModule *module) {
211
212
	g_type_module_use(G_TYPE_MODULE(module));
213
214
	g_io_extension_point_implement(G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
215
	    G_TYPE_KQUEUE_FILE_MONITOR, "kqueue", 10);
216
	g_io_extension_point_implement(G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
217
	    G_TYPE_KQUEUE_FILE_MONITOR, "kqueue", 10);
218
}
219
220
void
221
g_io_module_unload(GIOModule *module) {
222
223
	g_assert_not_reached();
224
}
(-)devel/glib20/files/kqueue_Makefile.in (+1533 lines)
Line 0 Link Here
1
# Makefile.in generated by automake 1.16.1 from Makefile.am.
2
# @configure_input@
3
4
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
5
6
# This Makefile.in is free software; the Free Software Foundation
7
# gives unlimited permission to copy and/or distribute it,
8
# with or without modifications, as long as this notice is preserved.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13
# PARTICULAR PURPOSE.
14
15
@SET_MAKE@
16
17
# GLIB - Library of useful C routines
18
19
20
21
22
VPATH = @srcdir@
23
am__is_gnu_make = { \
24
  if test -z '$(MAKELEVEL)'; then \
25
    false; \
26
  elif test -n '$(MAKE_HOST)'; then \
27
    true; \
28
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
29
    true; \
30
  else \
31
    false; \
32
  fi; \
33
}
34
am__make_running_with_option = \
35
  case $${target_option-} in \
36
      ?) ;; \
37
      *) echo "am__make_running_with_option: internal error: invalid" \
38
              "target option '$${target_option-}' specified" >&2; \
39
         exit 1;; \
40
  esac; \
41
  has_opt=no; \
42
  sane_makeflags=$$MAKEFLAGS; \
43
  if $(am__is_gnu_make); then \
44
    sane_makeflags=$$MFLAGS; \
45
  else \
46
    case $$MAKEFLAGS in \
47
      *\\[\ \	]*) \
48
        bs=\\; \
49
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
50
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
51
    esac; \
52
  fi; \
53
  skip_next=no; \
54
  strip_trailopt () \
55
  { \
56
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
57
  }; \
58
  for flg in $$sane_makeflags; do \
59
    test $$skip_next = yes && { skip_next=no; continue; }; \
60
    case $$flg in \
61
      *=*|--*) continue;; \
62
        -*I) strip_trailopt 'I'; skip_next=yes;; \
63
      -*I?*) strip_trailopt 'I';; \
64
        -*O) strip_trailopt 'O'; skip_next=yes;; \
65
      -*O?*) strip_trailopt 'O';; \
66
        -*l) strip_trailopt 'l'; skip_next=yes;; \
67
      -*l?*) strip_trailopt 'l';; \
68
      -[dEDm]) skip_next=yes;; \
69
      -[JT]) skip_next=yes;; \
70
    esac; \
71
    case $$flg in \
72
      *$$target_option*) has_opt=yes; break;; \
73
    esac; \
74
  done; \
75
  test $$has_opt = yes
76
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
77
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
78
pkgdatadir = $(datadir)/@PACKAGE@
79
pkgincludedir = $(includedir)/@PACKAGE@
80
pkglibdir = $(libdir)/@PACKAGE@
81
pkglibexecdir = $(libexecdir)/@PACKAGE@
82
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
83
install_sh_DATA = $(install_sh) -c -m 644
84
install_sh_PROGRAM = $(install_sh) -c
85
install_sh_SCRIPT = $(install_sh) -c
86
INSTALL_HEADER = $(INSTALL_DATA)
87
transform = $(program_transform_name)
88
NORMAL_INSTALL = :
89
PRE_INSTALL = :
90
POST_INSTALL = :
91
NORMAL_UNINSTALL = :
92
PRE_UNINSTALL = :
93
POST_UNINSTALL = :
94
build_triplet = @build@
95
host_triplet = @host@
96
installed_test_PROGRAMS = $(am__EXEEXT_1)
97
noinst_PROGRAMS = $(am__EXEEXT_3)
98
check_PROGRAMS = $(am__EXEEXT_2)
99
TESTS = $(am__EXEEXT_1)
100
@OS_WIN32_TRUE@am__append_1 = $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \
101
@OS_WIN32_TRUE@         $(dist_test_scripts) $(dist_uninstalled_test_scripts)
102
103
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_2 = $(all_test_ltlibs)
104
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_3 = $(all_test_programs)
105
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_4 = $(all_test_scripts)
106
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_5 = $(all_test_data)
107
@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_6 = $(all_test_ltlibs)
108
@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_7 = $(all_test_programs)
109
@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_8 = $(all_test_scripts)
110
@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__append_9 = $(all_test_data)
111
@ENABLE_INSTALLED_TESTS_TRUE@am__append_10 = $(test_programs) $(installed_test_programs) \
112
@ENABLE_INSTALLED_TESTS_TRUE@                          $(test_extra_programs) $(installed_test_extra_programs)
113
114
@ENABLE_INSTALLED_TESTS_TRUE@am__append_11 = $(test_scripts) \
115
@ENABLE_INSTALLED_TESTS_TRUE@	$(installed_test_scripts) \
116
@ENABLE_INSTALLED_TESTS_TRUE@	$(test_extra_scripts) \
117
@ENABLE_INSTALLED_TESTS_TRUE@	$(test_installed_extra_scripts) \
118
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_test_scripts) \
119
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_test_extra_scripts) \
120
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_installed_test_scripts) \
121
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_installed_test_extra_scripts)
122
@ENABLE_INSTALLED_TESTS_TRUE@am__append_12 = $(test_data) \
123
@ENABLE_INSTALLED_TESTS_TRUE@	$(installed_test_data) \
124
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_test_data) \
125
@ENABLE_INSTALLED_TESTS_TRUE@	$(dist_installed_test_data)
126
@ENABLE_INSTALLED_TESTS_TRUE@am__append_13 = $(test_ltlibraries) $(installed_test_ltlibraries)
127
@ENABLE_INSTALLED_TESTS_TRUE@am__append_14 = $(installed_test_meta_DATA)
128
subdir = gio/kqueue
129
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
130
am__aclocal_m4_deps = $(top_srcdir)/m4macros/attributes.m4 \
131
	$(top_srcdir)/m4macros/glibtests.m4 \
132
	$(top_srcdir)/m4macros/gtk-doc.m4 \
133
	$(top_srcdir)/m4macros/libtool.m4 \
134
	$(top_srcdir)/m4macros/ltoptions.m4 \
135
	$(top_srcdir)/m4macros/ltsugar.m4 \
136
	$(top_srcdir)/m4macros/ltversion.m4 \
137
	$(top_srcdir)/m4macros/lt~obsolete.m4 \
138
	$(top_srcdir)/acinclude.m4 $(top_srcdir)/acglib.m4 \
139
	$(top_srcdir)/glib/libcharset/codeset.m4 \
140
	$(top_srcdir)/glib/libcharset/glibc21.m4 \
141
	$(top_srcdir)/m4macros/glib-gettext.m4 \
142
	$(top_srcdir)/configure.ac
143
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
144
	$(ACLOCAL_M4)
145
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
146
mkinstalldirs = $(install_sh) -d
147
CONFIG_HEADER = $(top_builddir)/config.h
148
CONFIG_CLEAN_FILES =
149
CONFIG_CLEAN_VPATH_FILES =
150
am__EXEEXT_1 =
151
@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_2 = $(am__EXEEXT_1)
152
am__installdirs = "$(DESTDIR)$(installed_testdir)" \
153
	"$(DESTDIR)$(installed_testdir)" \
154
	"$(DESTDIR)$(installed_testdir)" \
155
	"$(DESTDIR)$(installed_test_metadir)" \
156
	"$(DESTDIR)$(installed_testdir)"
157
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_3 = $(am__EXEEXT_1)
158
PROGRAMS = $(installed_test_PROGRAMS) $(noinst_PROGRAMS)
159
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
160
am__vpath_adj = case $$p in \
161
    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
162
    *) f=$$p;; \
163
  esac;
164
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
165
am__install_max = 40
166
am__nobase_strip_setup = \
167
  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
168
am__nobase_strip = \
169
  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
170
am__nobase_list = $(am__nobase_strip_setup); \
171
  for p in $$list; do echo "$$p $$p"; done | \
172
  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
173
  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
174
    if (++n[$$2] == $(am__install_max)) \
175
      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
176
    END { for (dir in files) print dir, files[dir] }'
177
am__base_list = \
178
  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
179
  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
180
am__uninstall_files_from_dir = { \
181
  test -z "$$files" \
182
    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
183
    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
184
         $(am__cd) "$$dir" && rm -f $$files; }; \
185
  }
186
LTLIBRARIES = $(installed_test_LTLIBRARIES) $(noinst_LTLIBRARIES)
187
libkqueue_la_LIBADD =
188
am__objects_1 =
189
am_libkqueue_la_OBJECTS = libkqueue_la-gkqueuefilemonitor.lo \
190
	libkqueue_la-kqueue_fnm.lo $(am__objects_1)
191
libkqueue_la_OBJECTS = $(am_libkqueue_la_OBJECTS)
192
AM_V_lt = $(am__v_lt_@AM_V@)
193
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
194
am__v_lt_0 = --silent
195
am__v_lt_1 = 
196
libkqueue_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
197
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libkqueue_la_CFLAGS) \
198
	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
199
SCRIPTS = $(installed_test_SCRIPTS) $(noinst_SCRIPTS)
200
AM_V_P = $(am__v_P_@AM_V@)
201
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
202
am__v_P_0 = false
203
am__v_P_1 = :
204
AM_V_GEN = $(am__v_GEN_@AM_V@)
205
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
206
am__v_GEN_0 = @echo "  GEN     " $@;
207
am__v_GEN_1 = 
208
AM_V_at = $(am__v_at_@AM_V@)
209
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
210
am__v_at_0 = @
211
am__v_at_1 = 
212
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
213
depcomp = $(SHELL) $(top_srcdir)/depcomp
214
am__maybe_remake_depfiles = depfiles
215
am__depfiles_remade = ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo \
216
	./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo
217
am__mv = mv -f
218
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
219
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
220
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
221
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
222
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
223
	$(AM_CFLAGS) $(CFLAGS)
224
AM_V_CC = $(am__v_CC_@AM_V@)
225
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
226
am__v_CC_0 = @echo "  CC      " $@;
227
am__v_CC_1 = 
228
CCLD = $(CC)
229
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
230
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
231
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
232
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
233
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
234
am__v_CCLD_0 = @echo "  CCLD    " $@;
235
am__v_CCLD_1 = 
236
SOURCES = $(libkqueue_la_SOURCES)
237
DIST_SOURCES = $(libkqueue_la_SOURCES)
238
am__can_run_installinfo = \
239
  case $$AM_UPDATE_INFO_DIR in \
240
    n|no|NO) false;; \
241
    *) (install-info --version) >/dev/null 2>&1;; \
242
  esac
243
DATA = $(installed_test_meta_DATA) $(nobase_installed_test_DATA) \
244
	$(noinst_DATA)
245
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
246
# Read a list of newline-separated strings from the standard input,
247
# and print each of them once, without duplicates.  Input order is
248
# *not* preserved.
249
am__uniquify_input = $(AWK) '\
250
  BEGIN { nonempty = 0; } \
251
  { items[$$0] = 1; nonempty = 1; } \
252
  END { if (nonempty) { for (i in items) print i; }; } \
253
'
254
# Make sure the list of sources is unique.  This is necessary because,
255
# e.g., the same source file might be shared among _SOURCES variables
256
# for different programs/libraries.
257
am__define_uniq_tagged_files = \
258
  list='$(am__tagged_files)'; \
259
  unique=`for i in $$list; do \
260
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
261
  done | $(am__uniquify_input)`
262
ETAGS = etags
263
CTAGS = ctags
264
am__tty_colors_dummy = \
265
  mgn= red= grn= lgn= blu= brg= std=; \
266
  am__color_tests=no
267
am__tty_colors = { \
268
  $(am__tty_colors_dummy); \
269
  if test "X$(AM_COLOR_TESTS)" = Xno; then \
270
    am__color_tests=no; \
271
  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
272
    am__color_tests=yes; \
273
  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
274
    am__color_tests=yes; \
275
  fi; \
276
  if test $$am__color_tests = yes; then \
277
    red='[0;31m'; \
278
    grn='[0;32m'; \
279
    lgn='[1;32m'; \
280
    blu='[1;34m'; \
281
    mgn='[0;35m'; \
282
    brg='[1m'; \
283
    std='[m'; \
284
  fi; \
285
}
286
am__recheck_rx = ^[ 	]*:recheck:[ 	]*
287
am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
288
am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
289
# A command that, given a newline-separated list of test names on the
290
# standard input, print the name of the tests that are to be re-run
291
# upon "make recheck".
292
am__list_recheck_tests = $(AWK) '{ \
293
  recheck = 1; \
294
  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
295
    { \
296
      if (rc < 0) \
297
        { \
298
          if ((getline line2 < ($$0 ".log")) < 0) \
299
	    recheck = 0; \
300
          break; \
301
        } \
302
      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
303
        { \
304
          recheck = 0; \
305
          break; \
306
        } \
307
      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
308
        { \
309
          break; \
310
        } \
311
    }; \
312
  if (recheck) \
313
    print $$0; \
314
  close ($$0 ".trs"); \
315
  close ($$0 ".log"); \
316
}'
317
# A command that, given a newline-separated list of test names on the
318
# standard input, create the global log from their .trs and .log files.
319
am__create_global_log = $(AWK) ' \
320
function fatal(msg) \
321
{ \
322
  print "fatal: making $@: " msg | "cat >&2"; \
323
  exit 1; \
324
} \
325
function rst_section(header) \
326
{ \
327
  print header; \
328
  len = length(header); \
329
  for (i = 1; i <= len; i = i + 1) \
330
    printf "="; \
331
  printf "\n\n"; \
332
} \
333
{ \
334
  copy_in_global_log = 1; \
335
  global_test_result = "RUN"; \
336
  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
337
    { \
338
      if (rc < 0) \
339
         fatal("failed to read from " $$0 ".trs"); \
340
      if (line ~ /$(am__global_test_result_rx)/) \
341
        { \
342
          sub("$(am__global_test_result_rx)", "", line); \
343
          sub("[ 	]*$$", "", line); \
344
          global_test_result = line; \
345
        } \
346
      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
347
        copy_in_global_log = 0; \
348
    }; \
349
  if (copy_in_global_log) \
350
    { \
351
      rst_section(global_test_result ": " $$0); \
352
      while ((rc = (getline line < ($$0 ".log"))) != 0) \
353
      { \
354
        if (rc < 0) \
355
          fatal("failed to read from " $$0 ".log"); \
356
        print line; \
357
      }; \
358
      printf "\n"; \
359
    }; \
360
  close ($$0 ".trs"); \
361
  close ($$0 ".log"); \
362
}'
363
# Restructured Text title.
364
am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
365
# Solaris 10 'make', and several other traditional 'make' implementations,
366
# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
367
# by disabling -e (using the XSI extension "set +e") if it's set.
368
am__sh_e_setup = case $$- in *e*) set +e;; esac
369
# Default flags passed to test drivers.
370
am__common_driver_flags = \
371
  --color-tests "$$am__color_tests" \
372
  --enable-hard-errors "$$am__enable_hard_errors" \
373
  --expect-failure "$$am__expect_failure"
374
# To be inserted before the command running the test.  Creates the
375
# directory for the log if needed.  Stores in $dir the directory
376
# containing $f, in $tst the test, in $log the log.  Executes the
377
# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
378
# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
379
# will run the test scripts (or their associated LOG_COMPILER, if
380
# thy have one).
381
am__check_pre = \
382
$(am__sh_e_setup);					\
383
$(am__vpath_adj_setup) $(am__vpath_adj)			\
384
$(am__tty_colors);					\
385
srcdir=$(srcdir); export srcdir;			\
386
case "$@" in						\
387
  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
388
    *) am__odir=.;; 					\
389
esac;							\
390
test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
391
  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
392
if test -f "./$$f"; then dir=./;			\
393
elif test -f "$$f"; then dir=;				\
394
else dir="$(srcdir)/"; fi;				\
395
tst=$$dir$$f; log='$@'; 				\
396
if test -n '$(DISABLE_HARD_ERRORS)'; then		\
397
  am__enable_hard_errors=no; 				\
398
else							\
399
  am__enable_hard_errors=yes; 				\
400
fi; 							\
401
case " $(XFAIL_TESTS) " in				\
402
  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
403
    am__expect_failure=yes;;				\
404
  *)							\
405
    am__expect_failure=no;;				\
406
esac; 							\
407
$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
408
# A shell command to get the names of the tests scripts with any registered
409
# extension removed (i.e., equivalently, the names of the test logs, with
410
# the '.log' extension removed).  The result is saved in the shell variable
411
# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
412
# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
413
# since that might cause problem with VPATH rewrites for suffix-less tests.
414
# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
415
am__set_TESTS_bases = \
416
  bases='$(TEST_LOGS)'; \
417
  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
418
  bases=`echo $$bases`
419
RECHECK_LOGS = $(TEST_LOGS)
420
AM_RECURSIVE_TARGETS = check recheck
421
TEST_SUITE_LOG = test-suite.log
422
TEST_EXTENSIONS = @EXEEXT@ .test
423
am__test_logs1 = $(TESTS:=.log)
424
am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
425
TEST_LOGS = $(am__test_logs2:.test.log=.log)
426
TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
427
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
428
	$(TEST_LOG_FLAGS)
429
am__set_b = \
430
  case '$@' in \
431
    */*) \
432
      case '$*' in \
433
        */*) b='$*';; \
434
          *) b=`echo '$@' | sed 's/\.log$$//'`; \
435
       esac;; \
436
    *) \
437
      b='$*';; \
438
  esac
439
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
440
	$(top_srcdir)/glib.mk $(top_srcdir)/test-driver
441
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
442
ABS_TAPSET_DIR = @ABS_TAPSET_DIR@
443
ACLOCAL = @ACLOCAL@
444
ALLOCA = @ALLOCA@
445
AMTAR = @AMTAR@
446
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
447
AR = @AR@
448
AS = @AS@
449
AUTOCONF = @AUTOCONF@
450
AUTOHEADER = @AUTOHEADER@
451
AUTOMAKE = @AUTOMAKE@
452
AWK = @AWK@
453
CARBON_LIBS = @CARBON_LIBS@
454
CATALOGS = @CATALOGS@
455
CATOBJEXT = @CATOBJEXT@
456
CC = @CC@
457
CCDEPMODE = @CCDEPMODE@
458
CFLAGS = @CFLAGS@
459
COCOA_LIBS = @COCOA_LIBS@
460
CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@
461
CPP = @CPP@
462
CPPFLAGS = @CPPFLAGS@
463
CXX = @CXX@
464
CXXCPP = @CXXCPP@
465
CXXDEPMODE = @CXXDEPMODE@
466
CXXFLAGS = @CXXFLAGS@
467
CYGPATH_W = @CYGPATH_W@
468
DATADIRNAME = @DATADIRNAME@
469
DBUS1_CFLAGS = @DBUS1_CFLAGS@
470
DBUS1_LIBS = @DBUS1_LIBS@
471
DBUS_DAEMON = @DBUS_DAEMON@
472
DEFS = @DEFS@
473
DEPDIR = @DEPDIR@
474
DLLTOOL = @DLLTOOL@
475
DSYMUTIL = @DSYMUTIL@
476
DTRACE = @DTRACE@
477
DUMPBIN = @DUMPBIN@
478
ECHO_C = @ECHO_C@
479
ECHO_N = @ECHO_N@
480
ECHO_T = @ECHO_T@
481
EGREP = @EGREP@
482
EXEEXT = @EXEEXT@
483
FAM_LIBS = @FAM_LIBS@
484
FGREP = @FGREP@
485
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
486
GIO = @GIO@
487
GIO_MODULE_DIR = @GIO_MODULE_DIR@
488
GLIBC21 = @GLIBC21@
489
GLIB_BINARY_AGE = @GLIB_BINARY_AGE@
490
GLIB_DEBUG_FLAGS = @GLIB_DEBUG_FLAGS@
491
GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@
492
GLIB_HIDDEN_VISIBILITY_CFLAGS = @GLIB_HIDDEN_VISIBILITY_CFLAGS@
493
GLIB_INTERFACE_AGE = @GLIB_INTERFACE_AGE@
494
GLIB_LINK_FLAGS = @GLIB_LINK_FLAGS@
495
GLIB_MAJOR_VERSION = @GLIB_MAJOR_VERSION@
496
GLIB_MICRO_VERSION = @GLIB_MICRO_VERSION@
497
GLIB_MINOR_VERSION = @GLIB_MINOR_VERSION@
498
GLIB_RUNTIME_LIBDIR = @GLIB_RUNTIME_LIBDIR@
499
GLIB_VERSION = @GLIB_VERSION@
500
GLIB_WARN_CFLAGS = @GLIB_WARN_CFLAGS@
501
GLIB_WIN32_STATIC_COMPILATION_DEFINE = @GLIB_WIN32_STATIC_COMPILATION_DEFINE@
502
GMOFILES = @GMOFILES@
503
GMSGFMT = @GMSGFMT@
504
GREP = @GREP@
505
GSPAWN = @GSPAWN@
506
GTHREAD_COMPILE_IMPL_DEFINES = @GTHREAD_COMPILE_IMPL_DEFINES@
507
GTKDOC_CHECK = @GTKDOC_CHECK@
508
GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
509
GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
510
GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
511
GTKDOC_MKPDF = @GTKDOC_MKPDF@
512
GTKDOC_REBASE = @GTKDOC_REBASE@
513
G_LIBS_EXTRA = @G_LIBS_EXTRA@
514
G_MODULE_BROKEN_RTLD_GLOBAL = @G_MODULE_BROKEN_RTLD_GLOBAL@
515
G_MODULE_HAVE_DLERROR = @G_MODULE_HAVE_DLERROR@
516
G_MODULE_IMPL = @G_MODULE_IMPL@
517
G_MODULE_LDFLAGS = @G_MODULE_LDFLAGS@
518
G_MODULE_LIBS = @G_MODULE_LIBS@
519
G_MODULE_LIBS_EXTRA = @G_MODULE_LIBS_EXTRA@
520
G_MODULE_NEED_USCORE = @G_MODULE_NEED_USCORE@
521
G_MODULE_PLUGIN_LIBS = @G_MODULE_PLUGIN_LIBS@
522
G_MODULE_SUPPORTED = @G_MODULE_SUPPORTED@
523
G_THREAD_CFLAGS = @G_THREAD_CFLAGS@
524
G_THREAD_LIBS = @G_THREAD_LIBS@
525
G_THREAD_LIBS_EXTRA = @G_THREAD_LIBS_EXTRA@
526
G_THREAD_LIBS_FOR_GTHREAD = @G_THREAD_LIBS_FOR_GTHREAD@
527
HTML_DIR = @HTML_DIR@
528
ICONV_LIBS = @ICONV_LIBS@
529
INDENT = @INDENT@
530
INSTALL = @INSTALL@
531
INSTALL_DATA = @INSTALL_DATA@
532
INSTALL_PROGRAM = @INSTALL_PROGRAM@
533
INSTALL_SCRIPT = @INSTALL_SCRIPT@
534
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
535
INSTOBJEXT = @INSTOBJEXT@
536
INTLLIBS = @INTLLIBS@
537
LD = @LD@
538
LDFLAGS = @LDFLAGS@
539
LIBELF_CFLAGS = @LIBELF_CFLAGS@
540
LIBELF_LIBS = @LIBELF_LIBS@
541
LIBFFI_CFLAGS = @LIBFFI_CFLAGS@
542
LIBFFI_LIBS = @LIBFFI_LIBS@
543
LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
544
LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
545
LIBOBJS = @LIBOBJS@
546
LIBS = @LIBS@
547
LIBTOOL = @LIBTOOL@
548
LIB_EXE_MACHINE_FLAG = @LIB_EXE_MACHINE_FLAG@
549
LIPO = @LIPO@
550
LN_S = @LN_S@
551
LTLIBOBJS = @LTLIBOBJS@
552
LTP = @LTP@
553
LTP_GENHTML = @LTP_GENHTML@
554
LT_AGE = @LT_AGE@
555
LT_CURRENT = @LT_CURRENT@
556
LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@
557
LT_RELEASE = @LT_RELEASE@
558
LT_REVISION = @LT_REVISION@
559
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
560
MAINT = @MAINT@
561
MAKEINFO = @MAKEINFO@
562
MANIFEST_TOOL = @MANIFEST_TOOL@
563
MKDIR_P = @MKDIR_P@
564
MKINSTALLDIRS = @MKINSTALLDIRS@
565
MSGFMT = @MSGFMT@
566
MSGFMT_OPTS = @MSGFMT_OPTS@
567
NAMESER_COMPAT_INCLUDE = @NAMESER_COMPAT_INCLUDE@
568
NETWORK_LIBS = @NETWORK_LIBS@
569
NM = @NM@
570
NMEDIT = @NMEDIT@
571
OBJDUMP = @OBJDUMP@
572
OBJEXT = @OBJEXT@
573
OTOOL = @OTOOL@
574
OTOOL64 = @OTOOL64@
575
PACKAGE = @PACKAGE@
576
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
577
PACKAGE_NAME = @PACKAGE_NAME@
578
PACKAGE_STRING = @PACKAGE_STRING@
579
PACKAGE_TARNAME = @PACKAGE_TARNAME@
580
PACKAGE_URL = @PACKAGE_URL@
581
PACKAGE_VERSION = @PACKAGE_VERSION@
582
PATH_SEPARATOR = @PATH_SEPARATOR@
583
PCRE_CFLAGS = @PCRE_CFLAGS@
584
PCRE_LIBS = @PCRE_LIBS@
585
PCRE_REQUIRES = @PCRE_REQUIRES@
586
PCRE_WARN_CFLAGS = @PCRE_WARN_CFLAGS@
587
PERL = @PERL@
588
PERL_PATH = @PERL_PATH@
589
PKG_CONFIG = @PKG_CONFIG@
590
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
591
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
592
PLATFORMDEP = @PLATFORMDEP@
593
POFILES = @POFILES@
594
POSUB = @POSUB@
595
PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
596
PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
597
PYTHON = @PYTHON@
598
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
599
PYTHON_PLATFORM = @PYTHON_PLATFORM@
600
PYTHON_PREFIX = @PYTHON_PREFIX@
601
PYTHON_VERSION = @PYTHON_VERSION@
602
RANLIB = @RANLIB@
603
REBUILD = @REBUILD@
604
SED = @SED@
605
SELINUX_LIBS = @SELINUX_LIBS@
606
SET_MAKE = @SET_MAKE@
607
SHELL = @SHELL@
608
SHTOOL = @SHTOOL@
609
STRIP = @STRIP@
610
USE_NLS = @USE_NLS@
611
VERSION = @VERSION@
612
WINDRES = @WINDRES@
613
WSPIAPI_INCLUDE = @WSPIAPI_INCLUDE@
614
XATTR_LIBS = @XATTR_LIBS@
615
XGETTEXT = @XGETTEXT@
616
XMLCATALOG = @XMLCATALOG@
617
XML_CATALOG_FILE = @XML_CATALOG_FILE@
618
XSLTPROC = @XSLTPROC@
619
ZLIB_CFLAGS = @ZLIB_CFLAGS@
620
ZLIB_LIBS = @ZLIB_LIBS@
621
abs_builddir = @abs_builddir@
622
abs_srcdir = @abs_srcdir@
623
abs_top_builddir = @abs_top_builddir@
624
abs_top_srcdir = @abs_top_srcdir@
625
ac_ct_AR = @ac_ct_AR@
626
ac_ct_CC = @ac_ct_CC@
627
ac_ct_CXX = @ac_ct_CXX@
628
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
629
am__include = @am__include@
630
am__leading_dot = @am__leading_dot@
631
am__quote = @am__quote@
632
am__tar = @am__tar@
633
am__untar = @am__untar@
634
bindir = @bindir@
635
build = @build@
636
build_alias = @build_alias@
637
build_cpu = @build_cpu@
638
build_os = @build_os@
639
build_vendor = @build_vendor@
640
builddir = @builddir@
641
config_h_INCLUDES = @config_h_INCLUDES@
642
datadir = @datadir@
643
datarootdir = @datarootdir@
644
docdir = @docdir@
645
dvidir = @dvidir@
646
exec_prefix = @exec_prefix@
647
gio_INCLUDES = @gio_INCLUDES@
648
glib_INCLUDES = @glib_INCLUDES@
649
gmodule_INCLUDES = @gmodule_INCLUDES@
650
gobject_INCLUDES = @gobject_INCLUDES@
651
host = @host@
652
host_alias = @host_alias@
653
host_cpu = @host_cpu@
654
host_os = @host_os@
655
host_vendor = @host_vendor@
656
htmldir = @htmldir@
657
includedir = @includedir@
658
infodir = @infodir@
659
install_sh = @install_sh@
660
installed_test_metadir = @installed_test_metadir@
661
installed_testdir = @installed_testdir@
662
libdir = @libdir@
663
libexecdir = @libexecdir@
664
localedir = @localedir@
665
localstatedir = @localstatedir@
666
mandir = @mandir@
667
mkdir_p = @mkdir_p@
668
ms_librarian = @ms_librarian@
669
oldincludedir = @oldincludedir@
670
pdfdir = @pdfdir@
671
pkgpyexecdir = @pkgpyexecdir@
672
pkgpythondir = @pkgpythondir@
673
prefix = @prefix@
674
program_transform_name = @program_transform_name@
675
psdir = @psdir@
676
pyexecdir = @pyexecdir@
677
pythondir = @pythondir@
678
sbindir = @sbindir@
679
sharedstatedir = @sharedstatedir@
680
srcdir = @srcdir@
681
sysconfdir = @sysconfdir@
682
target_alias = @target_alias@
683
top_build_prefix = @top_build_prefix@
684
top_builddir = @top_builddir@
685
top_srcdir = @top_srcdir@
686
687
#GTESTER = gtester 			# for non-GLIB packages
688
#GTESTER_REPORT = gtester-report        # for non-GLIB packages
689
GTESTER = $(top_builddir)/glib/gtester			# for the GLIB package
690
GTESTER_REPORT = $(top_builddir)/glib/gtester-report	# for the GLIB package
691
NULL = 
692
693
# initialize variables for unconditional += appending
694
BUILT_SOURCES = 
695
BUILT_EXTRA_DIST = 
696
CLEANFILES = *.log *.trs $(am__append_14)
697
DISTCLEANFILES = 
698
MAINTAINERCLEANFILES = 
699
EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data)
700
701
# We support a fairly large range of possible variables.  It is expected that all types of files in a test suite
702
# will belong in exactly one of the following variables.
703
#
704
# First, we support the usual automake suffixes, but in lowercase, with the customary meaning:
705
#
706
#   test_programs, test_scripts, test_data, test_ltlibraries
707
#
708
# The above are used to list files that are involved in both uninstalled and installed testing.  The
709
# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite.
710
# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is
711
# installed in the same way as it appears in the package layout.
712
#
713
# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled',
714
# like so:
715
#
716
#   installed_test_programs, uninstalled_test_programs
717
#   installed_test_scripts, uninstalled_test_scripts
718
#   installed_test_data, uninstalled_test_data
719
#   installed_test_ltlibraries, uninstalled_test_ltlibraries
720
#
721
# Additionally, we support 'extra' infixes for programs and scripts.  This is used for support programs/scripts
722
# that should not themselves be run as testcases (but exist to be used from other testcases):
723
#
724
#   test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs
725
#   test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts
726
#
727
# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data
728
# file automatically end up in the tarball.
729
#
730
#   dist_test_scripts, dist_test_data, dist_test_extra_scripts
731
#   dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts
732
#   dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts
733
#
734
# Note that no file is automatically disted unless it appears in one of the dist_ variables.  This follows the
735
# standard automake convention of not disting programs scripts or data by default.
736
#
737
# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted
738
# variants) will be run as part of the in-tree 'make check'.  These are all assumed to be runnable under
739
# gtester.  That's a bit strange for scripts, but it's possible.
740
741
# we use test -z "$(TEST_PROGS)" above, so make sure we have no extra whitespace...
742
TEST_PROGS = $(strip $(test_programs) $(test_scripts) \
743
	$(uninstalled_test_programs) $(uninstalled_test_scripts) \
744
	$(dist_test_scripts) $(dist_uninstalled_test_scripts))
745
installed_test_LTLIBRARIES = $(am__append_13)
746
installed_test_SCRIPTS = $(am__append_11)
747
nobase_installed_test_DATA = $(am__append_12)
748
noinst_LTLIBRARIES = $(am__append_2) libkqueue.la
749
noinst_SCRIPTS = $(am__append_4)
750
noinst_DATA = $(am__append_5)
751
check_LTLIBRARIES = $(am__append_6)
752
check_SCRIPTS = $(am__append_8)
753
check_DATA = $(am__append_9)
754
755
# Note: build even the installed-only targets during 'make check' to ensure that they still work.
756
# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to
757
# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were
758
# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'.
759
all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \
760
                        $(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs)
761
762
all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) \
763
	$(installed_test_scripts) $(test_extra_scripts) \
764
	$(uninstalled_test_extra_scripts) \
765
	$(installed_test_extra_scripts) $(all_dist_test_scripts)
766
all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \
767
                        $(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts)
768
769
all_test_data = $(test_data) $(uninstalled_test_data) \
770
	$(installed_test_data) $(all_dist_test_data)
771
all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data)
772
all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries)
773
@ENABLE_INSTALLED_TESTS_TRUE@installed_testcases = $(test_programs) $(installed_test_programs) \
774
@ENABLE_INSTALLED_TESTS_TRUE@                      $(test_scripts) $(installed_test_scripts) \
775
@ENABLE_INSTALLED_TESTS_TRUE@                      $(dist_test_scripts) $(dist_installed_test_scripts)
776
777
@ENABLE_INSTALLED_TESTS_TRUE@installed_test_meta_DATA = $(installed_testcases:=.test)
778
libkqueue_la_SOURCES = \
779
       gkqueuefilemonitor.c \
780
       kqueue_fnm.c \
781
       kqueue_fnm.h \
782
       $(NULL)
783
784
libkqueue_la_CFLAGS = \
785
       $(GLIB_HIDDEN_VISIBILITY_CFLAGS) \
786
       -DG_LOG_DOMAIN=\"GLib-GIO\" \
787
       $(gio_INCLUDES) \
788
       $(GLIB_DEBUG_FLAGS) \
789
       -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \
790
       -DGIO_COMPILATION \
791
       -DG_DISABLE_DEPRECATED
792
793
all: $(BUILT_SOURCES)
794
	$(MAKE) $(AM_MAKEFLAGS) all-am
795
796
.SUFFIXES:
797
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
798
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/glib.mk $(am__configure_deps)
799
	@for dep in $?; do \
800
	  case '$(am__configure_deps)' in \
801
	    *$$dep*) \
802
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
803
	        && { if test -f $@; then exit 0; else break; fi; }; \
804
	      exit 1;; \
805
	  esac; \
806
	done; \
807
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gio/kqueue/Makefile'; \
808
	$(am__cd) $(top_srcdir) && \
809
	  $(AUTOMAKE) --gnu gio/kqueue/Makefile
810
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
811
	@case '$?' in \
812
	  *config.status*) \
813
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
814
	  *) \
815
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
816
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
817
	esac;
818
$(top_srcdir)/glib.mk $(am__empty):
819
820
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
821
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
822
823
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
824
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
825
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
826
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
827
$(am__aclocal_m4_deps):
828
829
clean-checkPROGRAMS:
830
	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
831
	echo " rm -f" $$list; \
832
	rm -f $$list || exit $$?; \
833
	test -n "$(EXEEXT)" || exit 0; \
834
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
835
	echo " rm -f" $$list; \
836
	rm -f $$list
837
install-installed_testPROGRAMS: $(installed_test_PROGRAMS)
838
	@$(NORMAL_INSTALL)
839
	@list='$(installed_test_PROGRAMS)'; test -n "$(installed_testdir)" || list=; \
840
	if test -n "$$list"; then \
841
	  echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \
842
	  $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \
843
	fi; \
844
	for p in $$list; do echo "$$p $$p"; done | \
845
	sed 's/$(EXEEXT)$$//' | \
846
	while read p p1; do if test -f $$p \
847
	 || test -f $$p1 \
848
	  ; then echo "$$p"; echo "$$p"; else :; fi; \
849
	done | \
850
	sed -e 'p;s,.*/,,;n;h' \
851
	    -e 's|.*|.|' \
852
	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
853
	sed 'N;N;N;s,\n, ,g' | \
854
	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
855
	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
856
	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
857
	    else { print "f", $$3 "/" $$4, $$1; } } \
858
	  END { for (d in files) print "f", d, files[d] }' | \
859
	while read type dir files; do \
860
	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
861
	    test -z "$$files" || { \
862
	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(installed_testdir)$$dir'"; \
863
	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(installed_testdir)$$dir" || exit $$?; \
864
	    } \
865
	; done
866
867
uninstall-installed_testPROGRAMS:
868
	@$(NORMAL_UNINSTALL)
869
	@list='$(installed_test_PROGRAMS)'; test -n "$(installed_testdir)" || list=; \
870
	files=`for p in $$list; do echo "$$p"; done | \
871
	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
872
	      -e 's/$$/$(EXEEXT)/' \
873
	`; \
874
	test -n "$$list" || exit 0; \
875
	echo " ( cd '$(DESTDIR)$(installed_testdir)' && rm -f" $$files ")"; \
876
	cd "$(DESTDIR)$(installed_testdir)" && rm -f $$files
877
878
clean-installed_testPROGRAMS:
879
	@list='$(installed_test_PROGRAMS)'; test -n "$$list" || exit 0; \
880
	echo " rm -f" $$list; \
881
	rm -f $$list || exit $$?; \
882
	test -n "$(EXEEXT)" || exit 0; \
883
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
884
	echo " rm -f" $$list; \
885
	rm -f $$list
886
887
clean-noinstPROGRAMS:
888
	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
889
	echo " rm -f" $$list; \
890
	rm -f $$list || exit $$?; \
891
	test -n "$(EXEEXT)" || exit 0; \
892
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
893
	echo " rm -f" $$list; \
894
	rm -f $$list
895
896
clean-checkLTLIBRARIES:
897
	-test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
898
	@list='$(check_LTLIBRARIES)'; \
899
	locs=`for p in $$list; do echo $$p; done | \
900
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
901
	      sort -u`; \
902
	test -z "$$locs" || { \
903
	  echo rm -f $${locs}; \
904
	  rm -f $${locs}; \
905
	}
906
907
install-installed_testLTLIBRARIES: $(installed_test_LTLIBRARIES)
908
	@$(NORMAL_INSTALL)
909
	@list='$(installed_test_LTLIBRARIES)'; test -n "$(installed_testdir)" || list=; \
910
	list2=; for p in $$list; do \
911
	  if test -f $$p; then \
912
	    list2="$$list2 $$p"; \
913
	  else :; fi; \
914
	done; \
915
	test -z "$$list2" || { \
916
	  echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \
917
	  $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \
918
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(installed_testdir)'"; \
919
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(installed_testdir)"; \
920
	}
921
922
uninstall-installed_testLTLIBRARIES:
923
	@$(NORMAL_UNINSTALL)
924
	@list='$(installed_test_LTLIBRARIES)'; test -n "$(installed_testdir)" || list=; \
925
	for p in $$list; do \
926
	  $(am__strip_dir) \
927
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(installed_testdir)/$$f'"; \
928
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(installed_testdir)/$$f"; \
929
	done
930
931
clean-installed_testLTLIBRARIES:
932
	-test -z "$(installed_test_LTLIBRARIES)" || rm -f $(installed_test_LTLIBRARIES)
933
	@list='$(installed_test_LTLIBRARIES)'; \
934
	locs=`for p in $$list; do echo $$p; done | \
935
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
936
	      sort -u`; \
937
	test -z "$$locs" || { \
938
	  echo rm -f $${locs}; \
939
	  rm -f $${locs}; \
940
	}
941
942
clean-noinstLTLIBRARIES:
943
	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
944
	@list='$(noinst_LTLIBRARIES)'; \
945
	locs=`for p in $$list; do echo $$p; done | \
946
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
947
	      sort -u`; \
948
	test -z "$$locs" || { \
949
	  echo rm -f $${locs}; \
950
	  rm -f $${locs}; \
951
	}
952
953
libkqueue.la: $(libkqueue_la_OBJECTS) $(libkqueue_la_DEPENDENCIES) $(EXTRA_libkqueue_la_DEPENDENCIES) 
954
	$(AM_V_CCLD)$(libkqueue_la_LINK)  $(libkqueue_la_OBJECTS) $(libkqueue_la_LIBADD) $(LIBS)
955
install-installed_testSCRIPTS: $(installed_test_SCRIPTS)
956
	@$(NORMAL_INSTALL)
957
	@list='$(installed_test_SCRIPTS)'; test -n "$(installed_testdir)" || list=; \
958
	if test -n "$$list"; then \
959
	  echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \
960
	  $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \
961
	fi; \
962
	for p in $$list; do \
963
	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
964
	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
965
	done | \
966
	sed -e 'p;s,.*/,,;n' \
967
	    -e 'h;s|.*|.|' \
968
	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
969
	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
970
	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
971
	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
972
	      if (++n[d] == $(am__install_max)) { \
973
		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
974
	    else { print "f", d "/" $$4, $$1 } } \
975
	  END { for (d in files) print "f", d, files[d] }' | \
976
	while read type dir files; do \
977
	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
978
	     test -z "$$files" || { \
979
	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(installed_testdir)$$dir'"; \
980
	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(installed_testdir)$$dir" || exit $$?; \
981
	     } \
982
	; done
983
984
uninstall-installed_testSCRIPTS:
985
	@$(NORMAL_UNINSTALL)
986
	@list='$(installed_test_SCRIPTS)'; test -n "$(installed_testdir)" || exit 0; \
987
	files=`for p in $$list; do echo "$$p"; done | \
988
	       sed -e 's,.*/,,;$(transform)'`; \
989
	dir='$(DESTDIR)$(installed_testdir)'; $(am__uninstall_files_from_dir)
990
991
mostlyclean-compile:
992
	-rm -f *.$(OBJEXT)
993
994
distclean-compile:
995
	-rm -f *.tab.c
996
997
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo@am__quote@ # am--include-marker
998
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo@am__quote@ # am--include-marker
999
1000
$(am__depfiles_remade):
1001
	@$(MKDIR_P) $(@D)
1002
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
1003
1004
am--depfiles: $(am__depfiles_remade)
1005
1006
.c.o:
1007
@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
1008
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
1009
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
1010
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1011
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
1012
1013
.c.obj:
1014
@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
1015
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
1016
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
1017
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1018
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
1019
1020
.c.lo:
1021
@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
1022
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
1023
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
1024
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1025
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
1026
1027
libkqueue_la-gkqueuefilemonitor.lo: gkqueuefilemonitor.c
1028
@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
1029
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Tpo $(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo
1030
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gkqueuefilemonitor.c' object='libkqueue_la-gkqueuefilemonitor.lo' libtool=yes @AMDEPBACKSLASH@
1031
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1032
@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
1033
1034
libkqueue_la-kqueue_fnm.lo: kqueue_fnm.c
1035
@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
1036
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libkqueue_la-kqueue_fnm.Tpo $(DEPDIR)/libkqueue_la-kqueue_fnm.Plo
1037
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kqueue_fnm.c' object='libkqueue_la-kqueue_fnm.lo' libtool=yes @AMDEPBACKSLASH@
1038
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1039
@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
1040
1041
mostlyclean-libtool:
1042
	-rm -f *.lo
1043
1044
clean-libtool:
1045
	-rm -rf .libs _libs
1046
install-installed_test_metaDATA: $(installed_test_meta_DATA)
1047
	@$(NORMAL_INSTALL)
1048
	@list='$(installed_test_meta_DATA)'; test -n "$(installed_test_metadir)" || list=; \
1049
	if test -n "$$list"; then \
1050
	  echo " $(MKDIR_P) '$(DESTDIR)$(installed_test_metadir)'"; \
1051
	  $(MKDIR_P) "$(DESTDIR)$(installed_test_metadir)" || exit 1; \
1052
	fi; \
1053
	for p in $$list; do \
1054
	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
1055
	  echo "$$d$$p"; \
1056
	done | $(am__base_list) | \
1057
	while read files; do \
1058
	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(installed_test_metadir)'"; \
1059
	  $(INSTALL_DATA) $$files "$(DESTDIR)$(installed_test_metadir)" || exit $$?; \
1060
	done
1061
1062
uninstall-installed_test_metaDATA:
1063
	@$(NORMAL_UNINSTALL)
1064
	@list='$(installed_test_meta_DATA)'; test -n "$(installed_test_metadir)" || list=; \
1065
	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
1066
	dir='$(DESTDIR)$(installed_test_metadir)'; $(am__uninstall_files_from_dir)
1067
install-nobase_installed_testDATA: $(nobase_installed_test_DATA)
1068
	@$(NORMAL_INSTALL)
1069
	@list='$(nobase_installed_test_DATA)'; test -n "$(installed_testdir)" || list=; \
1070
	if test -n "$$list"; then \
1071
	  echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)'"; \
1072
	  $(MKDIR_P) "$(DESTDIR)$(installed_testdir)" || exit 1; \
1073
	fi; \
1074
	$(am__nobase_list) | while read dir files; do \
1075
	  xfiles=; for file in $$files; do \
1076
	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
1077
	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
1078
	  test -z "$$xfiles" || { \
1079
	    test "x$$dir" = x. || { \
1080
	      echo " $(MKDIR_P) '$(DESTDIR)$(installed_testdir)/$$dir'"; \
1081
	      $(MKDIR_P) "$(DESTDIR)$(installed_testdir)/$$dir"; }; \
1082
	    echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(installed_testdir)/$$dir'"; \
1083
	    $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(installed_testdir)/$$dir" || exit $$?; }; \
1084
	done
1085
1086
uninstall-nobase_installed_testDATA:
1087
	@$(NORMAL_UNINSTALL)
1088
	@list='$(nobase_installed_test_DATA)'; test -n "$(installed_testdir)" || list=; \
1089
	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
1090
	dir='$(DESTDIR)$(installed_testdir)'; $(am__uninstall_files_from_dir)
1091
1092
ID: $(am__tagged_files)
1093
	$(am__define_uniq_tagged_files); mkid -fID $$unique
1094
tags: tags-am
1095
TAGS: tags
1096
1097
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
1098
	set x; \
1099
	here=`pwd`; \
1100
	$(am__define_uniq_tagged_files); \
1101
	shift; \
1102
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
1103
	  test -n "$$unique" || unique=$$empty_fix; \
1104
	  if test $$# -gt 0; then \
1105
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
1106
	      "$$@" $$unique; \
1107
	  else \
1108
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
1109
	      $$unique; \
1110
	  fi; \
1111
	fi
1112
ctags: ctags-am
1113
1114
CTAGS: ctags
1115
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
1116
	$(am__define_uniq_tagged_files); \
1117
	test -z "$(CTAGS_ARGS)$$unique" \
1118
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
1119
	     $$unique
1120
1121
GTAGS:
1122
	here=`$(am__cd) $(top_builddir) && pwd` \
1123
	  && $(am__cd) $(top_srcdir) \
1124
	  && gtags -i $(GTAGS_ARGS) "$$here"
1125
cscopelist: cscopelist-am
1126
1127
cscopelist-am: $(am__tagged_files)
1128
	list='$(am__tagged_files)'; \
1129
	case "$(srcdir)" in \
1130
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
1131
	  *) sdir=$(subdir)/$(srcdir) ;; \
1132
	esac; \
1133
	for i in $$list; do \
1134
	  if test -f "$$i"; then \
1135
	    echo "$(subdir)/$$i"; \
1136
	  else \
1137
	    echo "$$sdir/$$i"; \
1138
	  fi; \
1139
	done >> $(top_builddir)/cscope.files
1140
1141
distclean-tags:
1142
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
1143
1144
# Recover from deleted '.trs' file; this should ensure that
1145
# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
1146
# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
1147
# to avoid problems with "make -n".
1148
.log.trs:
1149
	rm -f $< $@
1150
	$(MAKE) $(AM_MAKEFLAGS) $<
1151
1152
# Leading 'am--fnord' is there to ensure the list of targets does not
1153
# expand to empty, as could happen e.g. with make check TESTS=''.
1154
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
1155
am--force-recheck:
1156
	@:
1157
1158
$(TEST_SUITE_LOG): $(TEST_LOGS)
1159
	@$(am__set_TESTS_bases); \
1160
	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
1161
	redo_bases=`for i in $$bases; do \
1162
	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
1163
	            done`; \
1164
	if test -n "$$redo_bases"; then \
1165
	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
1166
	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
1167
	  if $(am__make_dryrun); then :; else \
1168
	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
1169
	  fi; \
1170
	fi; \
1171
	if test -n "$$am__remaking_logs"; then \
1172
	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
1173
	       "recursion detected" >&2; \
1174
	elif test -n "$$redo_logs"; then \
1175
	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
1176
	fi; \
1177
	if $(am__make_dryrun); then :; else \
1178
	  st=0;  \
1179
	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
1180
	  for i in $$redo_bases; do \
1181
	    test -f $$i.trs && test -r $$i.trs \
1182
	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
1183
	    test -f $$i.log && test -r $$i.log \
1184
	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
1185
	  done; \
1186
	  test $$st -eq 0 || exit 1; \
1187
	fi
1188
	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
1189
	ws='[ 	]'; \
1190
	results=`for b in $$bases; do echo $$b.trs; done`; \
1191
	test -n "$$results" || results=/dev/null; \
1192
	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
1193
	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
1194
	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
1195
	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
1196
	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
1197
	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
1198
	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
1199
	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
1200
	  success=true; \
1201
	else \
1202
	  success=false; \
1203
	fi; \
1204
	br='==================='; br=$$br$$br$$br$$br; \
1205
	result_count () \
1206
	{ \
1207
	    if test x"$$1" = x"--maybe-color"; then \
1208
	      maybe_colorize=yes; \
1209
	    elif test x"$$1" = x"--no-color"; then \
1210
	      maybe_colorize=no; \
1211
	    else \
1212
	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
1213
	    fi; \
1214
	    shift; \
1215
	    desc=$$1 count=$$2; \
1216
	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
1217
	      color_start=$$3 color_end=$$std; \
1218
	    else \
1219
	      color_start= color_end=; \
1220
	    fi; \
1221
	    echo "$${color_start}# $$desc $$count$${color_end}"; \
1222
	}; \
1223
	create_testsuite_report () \
1224
	{ \
1225
	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
1226
	  result_count $$1 "PASS: " $$pass  "$$grn"; \
1227
	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
1228
	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
1229
	  result_count $$1 "FAIL: " $$fail  "$$red"; \
1230
	  result_count $$1 "XPASS:" $$xpass "$$red"; \
1231
	  result_count $$1 "ERROR:" $$error "$$mgn"; \
1232
	}; \
1233
	{								\
1234
	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
1235
	    $(am__rst_title);						\
1236
	  create_testsuite_report --no-color;				\
1237
	  echo;								\
1238
	  echo ".. contents:: :depth: 2";				\
1239
	  echo;								\
1240
	  for b in $$bases; do echo $$b; done				\
1241
	    | $(am__create_global_log);					\
1242
	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
1243
	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
1244
	if $$success; then						\
1245
	  col="$$grn";							\
1246
	 else								\
1247
	  col="$$red";							\
1248
	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
1249
	fi;								\
1250
	echo "$${col}$$br$${std}"; 					\
1251
	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
1252
	echo "$${col}$$br$${std}"; 					\
1253
	create_testsuite_report --maybe-color;				\
1254
	echo "$$col$$br$$std";						\
1255
	if $$success; then :; else					\
1256
	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
1257
	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
1258
	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
1259
	  fi;								\
1260
	  echo "$$col$$br$$std";					\
1261
	fi;								\
1262
	$$success || exit 1
1263
1264
check-TESTS: $(check_PROGRAMS) $(check_LTLIBRARIES) $(check_SCRIPTS) $(check_DATA)
1265
	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
1266
	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
1267
	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
1268
	@set +e; $(am__set_TESTS_bases); \
1269
	log_list=`for i in $$bases; do echo $$i.log; done`; \
1270
	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
1271
	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
1272
	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
1273
	exit $$?;
1274
recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) $(check_SCRIPTS) $(check_DATA)
1275
	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
1276
	@set +e; $(am__set_TESTS_bases); \
1277
	bases=`for i in $$bases; do echo $$i; done \
1278
	         | $(am__list_recheck_tests)` || exit 1; \
1279
	log_list=`for i in $$bases; do echo $$i.log; done`; \
1280
	log_list=`echo $$log_list`; \
1281
	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
1282
	        am__force_recheck=am--force-recheck \
1283
	        TEST_LOGS="$$log_list"; \
1284
	exit $$?
1285
.test.log:
1286
	@p='$<'; \
1287
	$(am__set_b); \
1288
	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
1289
	--log-file $$b.log --trs-file $$b.trs \
1290
	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
1291
	"$$tst" $(AM_TESTS_FD_REDIRECT)
1292
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
1293
@am__EXEEXT_TRUE@	@p='$<'; \
1294
@am__EXEEXT_TRUE@	$(am__set_b); \
1295
@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
1296
@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
1297
@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
1298
@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
1299
1300
distdir: $(BUILT_SOURCES)
1301
	$(MAKE) $(AM_MAKEFLAGS) distdir-am
1302
1303
distdir-am: $(DISTFILES)
1304
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
1305
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
1306
	list='$(DISTFILES)'; \
1307
	  dist_files=`for file in $$list; do echo $$file; done | \
1308
	  sed -e "s|^$$srcdirstrip/||;t" \
1309
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
1310
	case $$dist_files in \
1311
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
1312
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
1313
			   sort -u` ;; \
1314
	esac; \
1315
	for file in $$dist_files; do \
1316
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
1317
	  if test -d $$d/$$file; then \
1318
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
1319
	    if test -d "$(distdir)/$$file"; then \
1320
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
1321
	    fi; \
1322
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
1323
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
1324
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
1325
	    fi; \
1326
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
1327
	  else \
1328
	    test -f "$(distdir)/$$file" \
1329
	    || cp -p $$d/$$file "$(distdir)/$$file" \
1330
	    || exit 1; \
1331
	  fi; \
1332
	done
1333
check-am: all-am
1334
	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) \
1335
	  $(check_SCRIPTS) $(check_DATA)
1336
	$(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
1337
check: $(BUILT_SOURCES)
1338
	$(MAKE) $(AM_MAKEFLAGS) check-am
1339
all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(DATA)
1340
installdirs:
1341
	for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(installed_testdir)"; do \
1342
	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
1343
	done
1344
install: $(BUILT_SOURCES)
1345
	$(MAKE) $(AM_MAKEFLAGS) install-am
1346
install-exec: install-exec-am
1347
install-data: install-data-am
1348
uninstall: uninstall-am
1349
1350
install-am: all-am
1351
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
1352
1353
installcheck: installcheck-am
1354
install-strip:
1355
	if test -z '$(STRIP)'; then \
1356
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
1357
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
1358
	      install; \
1359
	else \
1360
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
1361
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
1362
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
1363
	fi
1364
mostlyclean-generic:
1365
	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
1366
	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
1367
	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
1368
1369
clean-generic:
1370
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
1371
1372
distclean-generic:
1373
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
1374
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
1375
	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
1376
1377
maintainer-clean-generic:
1378
	@echo "This command is intended for maintainers to use"
1379
	@echo "it deletes files that may require special tools to rebuild."
1380
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
1381
	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
1382
clean: clean-am
1383
1384
clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
1385
	clean-installed_testLTLIBRARIES clean-installed_testPROGRAMS \
1386
	clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
1387
	mostlyclean-am
1388
1389
distclean: distclean-am
1390
		-rm -f ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo
1391
	-rm -f ./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo
1392
	-rm -f Makefile
1393
distclean-am: clean-am distclean-compile distclean-generic \
1394
	distclean-tags
1395
1396
dvi: dvi-am
1397
1398
dvi-am:
1399
1400
html: html-am
1401
1402
html-am:
1403
1404
info: info-am
1405
1406
info-am:
1407
1408
install-data-am: install-installed_testLTLIBRARIES \
1409
	install-installed_testPROGRAMS install-installed_testSCRIPTS \
1410
	install-installed_test_metaDATA \
1411
	install-nobase_installed_testDATA
1412
1413
install-dvi: install-dvi-am
1414
1415
install-dvi-am:
1416
1417
install-exec-am:
1418
1419
install-html: install-html-am
1420
1421
install-html-am:
1422
1423
install-info: install-info-am
1424
1425
install-info-am:
1426
1427
install-man:
1428
1429
install-pdf: install-pdf-am
1430
1431
install-pdf-am:
1432
1433
install-ps: install-ps-am
1434
1435
install-ps-am:
1436
1437
installcheck-am:
1438
1439
maintainer-clean: maintainer-clean-am
1440
		-rm -f ./$(DEPDIR)/libkqueue_la-gkqueuefilemonitor.Plo
1441
	-rm -f ./$(DEPDIR)/libkqueue_la-kqueue_fnm.Plo
1442
	-rm -f Makefile
1443
maintainer-clean-am: distclean-am maintainer-clean-generic
1444
1445
mostlyclean: mostlyclean-am
1446
1447
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
1448
	mostlyclean-libtool
1449
1450
pdf: pdf-am
1451
1452
pdf-am:
1453
1454
ps: ps-am
1455
1456
ps-am:
1457
1458
uninstall-am: uninstall-installed_testLTLIBRARIES \
1459
	uninstall-installed_testPROGRAMS \
1460
	uninstall-installed_testSCRIPTS \
1461
	uninstall-installed_test_metaDATA \
1462
	uninstall-nobase_installed_testDATA
1463
1464
.MAKE: all check check-am install install-am install-strip
1465
1466
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
1467
	check-am check-local clean clean-checkLTLIBRARIES \
1468
	clean-checkPROGRAMS clean-generic \
1469
	clean-installed_testLTLIBRARIES clean-installed_testPROGRAMS \
1470
	clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
1471
	cscopelist-am ctags ctags-am distclean distclean-compile \
1472
	distclean-generic distclean-libtool distclean-tags distdir dvi \
1473
	dvi-am html html-am info info-am install install-am \
1474
	install-data install-data-am install-dvi install-dvi-am \
1475
	install-exec install-exec-am install-html install-html-am \
1476
	install-info install-info-am install-installed_testLTLIBRARIES \
1477
	install-installed_testPROGRAMS install-installed_testSCRIPTS \
1478
	install-installed_test_metaDATA install-man \
1479
	install-nobase_installed_testDATA install-pdf install-pdf-am \
1480
	install-ps install-ps-am install-strip installcheck \
1481
	installcheck-am installdirs maintainer-clean \
1482
	maintainer-clean-generic mostlyclean mostlyclean-compile \
1483
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
1484
	recheck tags tags-am uninstall uninstall-am \
1485
	uninstall-installed_testLTLIBRARIES \
1486
	uninstall-installed_testPROGRAMS \
1487
	uninstall-installed_testSCRIPTS \
1488
	uninstall-installed_test_metaDATA \
1489
	uninstall-nobase_installed_testDATA
1490
1491
.PRECIOUS: Makefile
1492
1493
1494
# test-nonrecursive: run tests only in cwd
1495
@OS_UNIX_TRUE@test-nonrecursive: ${TEST_PROGS}
1496
@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}
1497
@OS_UNIX_FALSE@test-nonrecursive:
1498
1499
.PHONY: test-nonrecursive
1500
1501
.PHONY: lcov genlcov lcov-clean
1502
# use recursive makes in order to ignore errors during check
1503
lcov:
1504
	-$(MAKE) $(AM_MAKEFLAGS) -k check
1505
	$(MAKE) $(AM_MAKEFLAGS) genlcov
1506
1507
# we have to massage the lcov.info file slightly to hide the effect of libtool
1508
# placing the objects files in the .libs/ directory separate from the *.c
1509
# we also have to delete tests/.libs/libmoduletestplugin_*.gcda
1510
genlcov:
1511
	$(AM_V_GEN) rm -f $(top_builddir)/tests/.libs/libmoduletestplugin_*.gcda; \
1512
	  $(LTP) --quiet --directory $(top_builddir) --capture --output-file glib-lcov.info --test-name GLIB_PERF --no-checksum --compat-libtool --ignore-errors source; \
1513
	  $(LTP) --quiet --output-file glib-lcov.info --remove glib-lcov.info docs/reference/\* /tmp/\*  gio/tests/gdbus-object-manager-example/\* ; \
1514
	  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
1515
	@echo "file://$(abs_top_builddir)/glib-lcov/index.html"
1516
1517
lcov-clean:
1518
	if test -n "$(LTP)"; then \
1519
	  $(LTP) --quiet --directory $(top_builddir) -z; \
1520
	fi
1521
1522
# run tests in cwd as part of make check
1523
check-local: test-nonrecursive
1524
1525
@ENABLE_INSTALLED_TESTS_TRUE@%.test: %$(EXEEXT) Makefile
1526
@ENABLE_INSTALLED_TESTS_TRUE@	$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
1527
@ENABLE_INSTALLED_TESTS_TRUE@	echo 'Type=session' >> $@.tmp; \
1528
@ENABLE_INSTALLED_TESTS_TRUE@	echo 'Exec=$(installed_testdir)/$(notdir $<)' >> $@.tmp; \
1529
@ENABLE_INSTALLED_TESTS_TRUE@	mv $@.tmp $@)
1530
1531
# Tell versions [3.59,3.63) of GNU make to not export all variables.
1532
# Otherwise a system limit (for SysV at least) may be exceeded.
1533
.NOEXPORT:
(-)devel/glib20/files/kqueue_fnm.c (+1431 lines)
Line 0 Link Here
1
/*-
2
 * Copyright (c) 2016 - 2019 Rozhuk Ivan <rozhuk.im@gmail.com>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 *
26
 * Author: Rozhuk Ivan <rozhuk.im@gmail.com>
27
 *
28
 */
29
30
#include <sys/param.h>
31
#include <sys/types.h>
32
#include <sys/event.h>
33
#include <sys/time.h>
34
#include <sys/stat.h>
35
#include <sys/ucred.h>
36
#include <sys/mount.h>
37
#include <sys/fcntl.h> /* open, fcntl */
38
#include <sys/queue.h>
39
40
#include <inttypes.h>
41
#include <stdlib.h> /* malloc, exit */
42
#include <unistd.h> /* close, write, sysconf */
43
#include <string.h> /* bcopy, bzero, memcpy, memmove, memset, strerror... */
44
#include <dirent.h> /* opendir, readdir */
45
#include <errno.h>
46
#include <pthread.h>
47
#include <glib.h>
48
49
#include "kqueue_fnm.h"
50
51
52
/* Preallocate items count. */
53
#ifndef FILES_ALLOC_BLK_SIZE
54
#	define FILES_ALLOC_BLK_SIZE	32
55
#endif
56
57
58
typedef struct readdir_context_s {
59
	int		fd;
60
	uint8_t		*buf;
61
	size_t		buf_size;
62
	size_t		buf_used;
63
	size_t		buf_pos;
64
} readdir_ctx_t, *readdir_ctx_p;
65
66
67
typedef struct file_info_s { /* Directory file. */
68
	int		fd;		/* For notify kqueue(). */
69
	struct dirent 	de;		/* d_reclen used for action. */
70
	struct stat	sb;
71
} file_info_t, *file_info_p;
72
73
74
typedef struct kq_file_nonify_monitor_obj_s	*kq_fnmo_p;
75
76
typedef struct kq_file_nonify_monitor_entry_s {
77
	TAILQ_ENTRY(kq_file_nonify_monitor_entry_s) next;
78
	kq_fnmo_p	fnmo;
79
	void		*udata;
80
	volatile int	enabled;
81
} kq_fnme_t;
82
83
TAILQ_HEAD(kq_fnme_head, kq_file_nonify_monitor_entry_s);
84
85
typedef struct kq_file_nonify_monitor_obj_s {
86
	int		fd;		/* For notify kqueue(). */
87
	int		is_dir;
88
	int		is_local;	/* Is file system local. */
89
	int		is_removed;	/* File/dir deleted, reported and can be only free. */
90
	int		is_cached;	/* Added to fnmo_cache. */
91
	struct stat	sb;
92
	char		path[(PATH_MAX + sizeof(void*))];
93
	size_t		path_size;
94
	size_t		name_offset;	/* Parent path size. */
95
	uint32_t	rate_lim_cur_interval;	/* From rate_limit_time_init to rate_limit_time_max. 0 disabled. */
96
	size_t		rate_lim_ev_cnt;	/* Events count then rate_lim_cur_interval != 0 since last report. */
97
	sbintime_t	rate_lim_ev_last;	/* Last event time. */
98
	void		*udata;
99
	kq_fnm_p	kfnm;
100
	struct kq_fnme_head entry_head;
101
	/* For dir. */
102
	file_info_p	files;
103
	volatile size_t	files_count;
104
	size_t		files_allocated;
105
} kq_fnmo_t;
106
107
108
typedef struct kq_file_nonify_monitor_s {
109
	int		fd;		/* kqueue() fd. */
110
	int		pfd[2];		/* pipe queue specific. */
111
	GHashTable	*fnmo_cache;
112
	struct statfs	*mounts;
113
	size_t		mounts_count;
114
	kfnm_event_handler_cb cb_func;	/* Callback on dir/file change. */
115
	kq_file_mon_settings_t s;
116
	sbintime_t	rate_lim_time_init; /* rate_limit_time_init */
117
	pthread_t	tid;
118
} kq_fnm_t;
119
120
121
typedef void (*kq_msg_cb)(void *arg);
122
123
typedef struct kq_file_mon_msg_pkt_s {
124
	size_t		magic;
125
	kq_msg_cb	msg_cb;
126
	void		*arg;
127
	size_t		chk_sum;
128
} kq_fnm_msg_pkt_t, *kq_fnm_msg_pkt_p;
129
130
#define KF_MSG_PKT_MAGIC	0xffddaa00
131
132
133
#ifndef O_NOATIME
134
#	define O_NOATIME	0
135
#endif
136
#ifndef O_EVTONLY
137
#	define O_EVTONLY	O_RDONLY
138
#endif
139
#define OPEN_FILE_FLAGS		(O_EVTONLY | O_NONBLOCK | O_NOFOLLOW | O_NOATIME | O_CLOEXEC)
140
141
#ifndef NOTE_CLOSE_WRITE
142
#	define NOTE_CLOSE_WRITE	0
143
#endif
144
#define EVFILT_VNODE_SUB_FLAGS	(NOTE_WRITE |				\
145
				NOTE_EXTEND |				\
146
				NOTE_ATTRIB |				\
147
				NOTE_LINK |				\
148
				NOTE_CLOSE_WRITE)
149
150
#define EVFILT_VNODE_FLAGS_ALL	(NOTE_DELETE |				\
151
				EVFILT_VNODE_SUB_FLAGS |		\
152
				NOTE_RENAME |				\
153
				NOTE_REVOKE)
154
155
#ifndef _GENERIC_DIRSIZ
156
#	define _GENERIC_DIRSIZ(__de)	MIN((__de)->d_reclen, sizeof(struct dirent))
157
#endif
158
159
#define IS_NAME_DOTS(__name)	('.' == (__name)[0] &&			\
160
				 ('\0' == (__name)[1] || 		\
161
				  ('.' == (__name)[1] && '\0' == (__name)[2])))
162
#define IS_DE_NAME_EQ(__de1, __de2)  (0 == mem_cmpn((__de1)->d_name,	\
163
						    (__de1)->d_namlen,	\
164
						    (__de2)->d_name,	\
165
						    (__de2)->d_namlen))
166
#define zalloc(__size)		calloc(1, (__size))
167
168
#if (!defined(HAVE_REALLOCARRAY) && (!defined(__FreeBSD_version) || __FreeBSD_version < 1100000))
169
#	define reallocarray(__mem, __size, __count)	realloc((__mem), ((__size) * (__count)))
170
#endif
171
172
/* To not depend from compiler version. */
173
#define MSTOSBT(__ms)		((sbintime_t)((((uint64_t)1 << 32) * (uint64_t)(__ms)) / 1000))
174
175
#ifndef TAILQ_FOREACH_SAFE
176
#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
177
	for ((var) = TAILQ_FIRST((head));				\
178
	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
179
	    (var) = (tvar))
180
#endif
181
182
#ifndef CLOCK_MONOTONIC_FAST
183
#	define CLOCK_MONOTONIC_FAST	CLOCK_MONOTONIC
184
#endif
185
186
187
void 	*kq_fnm_proccess_events_proc(void *data);
188
189
static inline int
190
mem_cmpn(const void *buf1, const size_t buf1_size,
191
    const void *buf2, const size_t buf2_size) {
192
193
	if (buf1_size != buf2_size)
194
		return (((buf1_size > buf2_size) ? 127 : -127));
195
	if (0 == buf1_size || buf1 == buf2)
196
		return (0);
197
	if (NULL == buf1)
198
		return (-127);
199
	if (NULL == buf2)
200
		return (127);
201
	return (memcmp(buf1, buf2, buf1_size));
202
}
203
204
static int
205
realloc_items(void **items, const size_t item_size,
206
    size_t *allocated, const size_t alloc_blk_cnt, const size_t count) {
207
	size_t allocated_prev, allocated_new;
208
	uint8_t *items_new;
209
210
	if (NULL == items || 0 == item_size || NULL == allocated ||
211
	    0 == alloc_blk_cnt)
212
		return (EINVAL);
213
	allocated_prev = (*allocated);
214
	if (NULL != (*items) &&
215
	    allocated_prev > count &&
216
	    allocated_prev <= (count + alloc_blk_cnt))
217
		return (0);
218
	allocated_new = (((count / alloc_blk_cnt) + 1) * alloc_blk_cnt);
219
	items_new = (uint8_t*)reallocarray((*items), item_size, allocated_new);
220
	if (NULL == items_new) /* Realloc fail! */
221
		return (ENOMEM);
222
223
	if (allocated_new > allocated_prev) { /* Init new mem. */
224
		memset((items_new + (allocated_prev * item_size)), 0x00,
225
		    ((allocated_new - allocated_prev) * item_size));
226
	}
227
	(*items) = items_new;
228
	(*allocated) = allocated_new;
229
230
	return (0);
231
}
232
233
/* Like getmntinfo() but allow free mem. */
234
static int
235
getmntinfo_ex(struct statfs **mntbufp, int mode) {
236
	int ret;
237
	struct statfs *buf;
238
239
	if (NULL == mntbufp)
240
		return (EINVAL);
241
	/* Request count. */
242
	ret = getfsstat(NULL, 0, mode);
243
	if (-1 == ret)
244
		return (ret);
245
	/* Alloc mem. */
246
	buf = calloc((ret + 1), sizeof(struct statfs));
247
	if (NULL == buf)
248
		return (-1);
249
	/* Request data. */
250
	ret = getfsstat(buf, ((ret + 1) * sizeof(struct statfs)), mode);
251
	if (-1 == ret) {
252
		free(buf);
253
		buf = NULL;
254
	}
255
	(*mntbufp) = buf;
256
257
	return (ret);
258
}
259
260
static int
261
mounts_find_name(struct statfs *mounts, size_t mounts_count,
262
    const char *mntonname) {
263
	size_t i;
264
265
	if (NULL == mounts || NULL == mntonname)
266
		return (0);
267
	for (i = 0; i < mounts_count; i ++) {
268
		if (0 != strncmp(mntonname, mounts[i].f_mntonname, MNAMELEN))
269
			continue;
270
		return (1);
271
	}
272
	return (0);
273
}
274
275
276
static int
277
readdir_start(int fd, struct stat *sb, size_t exp_count, readdir_ctx_p rdd) {
278
	size_t buf_size;
279
280
	if (-1 == fd || NULL == sb || NULL == rdd)
281
		return (EINVAL);
282
	if (-1 == lseek(fd, 0, SEEK_SET))
283
		return (errno);
284
	/* Calculate buf size for getdents(). */
285
	buf_size = MAX((size_t)sb->st_size, (exp_count * sizeof(struct dirent)));
286
	if (0 == buf_size) {
287
		buf_size = (16 * PAGE_SIZE);
288
	}
289
	/* Make buf size well aligned. */
290
	if (0 != sb->st_blksize) {
291
		if (powerof2(sb->st_blksize)) {
292
			buf_size = roundup2(buf_size, sb->st_blksize);
293
		} else {
294
			buf_size = roundup(buf_size, sb->st_blksize);
295
		}
296
	} else {
297
		buf_size = round_page(buf_size);
298
	}
299
	/* Init. */
300
	memset(rdd, 0x00, sizeof(readdir_ctx_t));
301
	rdd->buf = malloc(buf_size);
302
	if (NULL == rdd->buf)
303
		return (ENOMEM);
304
	rdd->buf_size = buf_size;
305
	rdd->fd = fd;
306
307
	return (0);
308
}
309
310
static void
311
readdir_free(readdir_ctx_p rdd) {
312
313
	if (NULL == rdd || NULL == rdd->buf)
314
		return;
315
	free(rdd->buf);
316
	memset(rdd, 0x00, sizeof(readdir_ctx_t));
317
}
318
319
static int
320
readdir_next(readdir_ctx_p rdd, struct dirent *de) {
321
	int error = 0;
322
	ssize_t ios;
323
	uint8_t *ptr;
324
325
	if (NULL == rdd || NULL == rdd->buf || NULL == de)
326
		return (EINVAL);
327
328
	for (;;) {
329
		if (rdd->buf_used <= rdd->buf_pos) {
330
			/* Called once if buf size calculated ok. */
331
			ios = getdents(rdd->fd, (char*)rdd->buf, rdd->buf_size);
332
			if (-1 == ios) {
333
				error = errno;
334
				break;
335
			}
336
			if (0 == ios) {
337
				error = ESPIPE; /* EOF. */
338
				break;
339
			}
340
			rdd->buf_used = (size_t)ios;
341
			rdd->buf_pos = 0;
342
		}
343
		/* Keep data aligned. */
344
		ptr = (rdd->buf + rdd->buf_pos);
345
		memcpy(de, ptr, (sizeof(struct dirent) - sizeof(de->d_name)));
346
		if (0 == de->d_reclen) {
347
			error = ESPIPE; /* EOF. */
348
			break;
349
		}
350
		rdd->buf_pos += de->d_reclen;
351
#ifdef DT_WHT
352
		if (DT_WHT == de->d_type)
353
			continue;
354
#endif
355
		if (0 == de->d_namlen)
356
			continue; /* Empty. */
357
		memcpy(de, ptr, _GENERIC_DIRSIZ(de));
358
		if (0 == de->d_name[0])
359
			continue; /* Empty. */
360
		if (IS_NAME_DOTS(de->d_name))
361
			continue; /* Dots. */
362
		return (0); /* OK. */
363
	}
364
365
	/* Err or no more files. */
366
	readdir_free(rdd);
367
368
	return (error);
369
}
370
371
372
static int
373
file_info_find_ni(file_info_p files, size_t files_count,
374
    file_info_p fi, size_t *idx) {
375
	size_t i;
376
	mode_t st_ftype;
377
378
	if (NULL == files || NULL == fi || NULL == idx)
379
		return (0);
380
	st_ftype = (S_IFMT & fi->sb.st_mode);
381
	for (i = 0; i < files_count; i ++) {
382
		if ((S_IFMT & files[i].sb.st_mode) != st_ftype)
383
			continue;
384
		if ((fi->sb.st_ino != files[i].sb.st_ino ||
385
		     fi->de.d_fileno != files[i].de.d_fileno) &&
386
		    0 == IS_DE_NAME_EQ(&fi->de, &files[i].de))
387
			continue;
388
		(*idx) = i;
389
		return (1);
390
	}
391
	(*idx) = files_count;
392
	return (0);
393
}
394
395
static int
396
file_info_find_ino(file_info_p files, size_t files_count,
397
    file_info_p fi, size_t *idx) {
398
	size_t i;
399
	mode_t st_ftype;
400
401
	if (NULL == files || NULL == fi || NULL == idx)
402
		return (0);
403
	st_ftype = (S_IFMT & fi->sb.st_mode);
404
	for (i = 0; i < files_count; i ++) {
405
		if ((S_IFMT & files[i].sb.st_mode) != st_ftype ||
406
		    fi->sb.st_ino != files[i].sb.st_ino ||
407
		    fi->de.d_fileno != files[i].de.d_fileno)
408
			continue;
409
		(*idx) = i;
410
		return (1);
411
	}
412
	(*idx) = files_count;
413
	return (0);
414
}
415
416
static int
417
file_info_find_name(file_info_p files, size_t files_count,
418
    file_info_p fi, size_t *idx) {
419
	size_t i;
420
	mode_t st_ftype;
421
422
	if (NULL == files || NULL == fi || NULL == idx)
423
		return (0);
424
	st_ftype = (S_IFMT & fi->sb.st_mode);
425
	for (i = 0; i < files_count; i ++) {
426
		if ((S_IFMT & files[i].sb.st_mode) != st_ftype ||
427
		    0 == IS_DE_NAME_EQ(&fi->de, &files[i].de))
428
			continue;
429
		(*idx) = i;
430
		return (1);
431
	}
432
	(*idx) = files_count;
433
	return (0);
434
}
435
436
static void
437
file_info_fd_close(file_info_p files, size_t files_count) {
438
	size_t i;
439
440
	if (NULL == files || 0 == files_count)
441
		return;
442
	for (i = 0; i < files_count; i ++) {
443
		if (-1 == files[i].fd)
444
			continue;
445
		close(files[i].fd);
446
		files[i].fd = -1;
447
	}
448
}
449
450
451
static int
452
is_fs_local(struct statfs *stfs, const char **local_fs, const char **non_local_fs) {
453
	size_t i;
454
455
	if (NULL == stfs)
456
		return (0);
457
	/* White listed fs. */
458
	if (NULL != local_fs) {
459
		for (i = 0; NULL != local_fs[i]; i ++) {
460
			if (0 == strncmp(stfs->f_fstypename, local_fs[i],
461
			    sizeof(stfs->f_fstypename)))
462
				return (1);
463
		}
464
	}
465
	if (0 == (MNT_LOCAL & stfs->f_flags))
466
		return (0);
467
	/* Filter out black listed fs. */
468
	if (NULL != non_local_fs) {
469
		for (i = 0; NULL != non_local_fs[i]; i ++) {
470
			if (0 == strncmp(stfs->f_fstypename, non_local_fs[i],
471
			    sizeof(stfs->f_fstypename)))
472
				return (0);
473
		}
474
	}
475
	return (1);
476
}
477
478
479
static void
480
kq_fnmo_rate_lim_stop(kq_fnmo_p fnmo) {
481
	struct kevent kev;
482
483
	if (NULL == fnmo || 0 == fnmo->rate_lim_cur_interval)
484
		return;
485
	fnmo->rate_lim_cur_interval = 0;
486
	fnmo->rate_lim_ev_cnt = 0;
487
	EV_SET(&kev, (uintptr_t)fnmo, EVFILT_TIMER,
488
	    (EV_DELETE | EV_CLEAR), 0, 0, NULL);
489
	kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL);
490
}
491
492
static int
493
kq_fnmo_rate_lim_shedule_next(kq_fnmo_p fnmo) {
494
	u_short flags = (EV_ADD | EV_CLEAR | EV_ONESHOT);
495
	struct kevent kev;
496
497
	if (NULL == fnmo || -1 == fnmo->fd ||
498
	    0 == fnmo->kfnm->s.rate_limit_time_init)
499
		return (EINVAL);
500
	if (0 == fnmo->rate_lim_cur_interval) { /* First call. */
501
		fnmo->rate_lim_cur_interval = fnmo->kfnm->s.rate_limit_time_init;
502
	} else {
503
		if (fnmo->rate_lim_cur_interval == fnmo->kfnm->s.rate_limit_time_max)
504
			return (0); /* No need to modify timer. */
505
		/* Increase rate limit interval. */
506
		fnmo->rate_lim_cur_interval *= fnmo->kfnm->s.rate_limit_time_mul;
507
	}
508
	if (fnmo->rate_lim_cur_interval >= fnmo->kfnm->s.rate_limit_time_max) {
509
		/* Check upper limit and shedule periodic timer with upper rate limit time. */
510
		flags &= ~EV_ONESHOT;
511
		fnmo->rate_lim_cur_interval = fnmo->kfnm->s.rate_limit_time_max;
512
	}
513
	/* Setup timer. */
514
	EV_SET(&kev, (uintptr_t)fnmo, EVFILT_TIMER, flags,
515
	    NOTE_MSECONDS, fnmo->rate_lim_cur_interval, fnmo);
516
	if (-1 == kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL)) {
517
		fnmo->rate_lim_cur_interval = 0;
518
		return (errno);
519
	}
520
	if (0 != (EV_ERROR & kev.flags)) {
521
		fnmo->rate_lim_cur_interval = 0;
522
		return ((int)kev.data);
523
	}
524
	return (0);
525
}
526
527
/* Return:
528
 * 0 for events that not handled
529
 * 1 for handled = rate limited
530
 * -1 on error.
531
 */
532
static int
533
kq_fnmo_rate_lim_check(kq_fnmo_p fnmo) {
534
	sbintime_t sbt, sbt_now;
535
	struct timespec ts;
536
537
	if (NULL == fnmo)
538
		return (-1);
539
	if (-1 == fnmo->fd ||
540
	    0 == fnmo->kfnm->s.rate_limit_time_init)
541
		return (0);
542
	if (0 != fnmo->rate_lim_cur_interval) {
543
		fnmo->rate_lim_ev_cnt ++; /* Count event, timer is active. */
544
		return (1);
545
	}
546
547
	/* Do we need to enable rate limit? */
548
	if (0 != clock_gettime(CLOCK_MONOTONIC_FAST, &ts))
549
		return (-1);
550
	sbt_now = tstosbt(ts);
551
	sbt = (fnmo->rate_lim_ev_last + fnmo->kfnm->rate_lim_time_init);
552
	fnmo->rate_lim_ev_last = sbt_now;
553
	if (sbt < sbt_now) /* Events rate to low. */
554
		return (0);
555
	/* Try to enable rate limit. */
556
	if (0 != kq_fnmo_rate_lim_shedule_next(fnmo))
557
		return (-1);
558
	/* Ok. */
559
	fnmo->rate_lim_ev_cnt ++;
560
561
	return (1);
562
}
563
564
static void
565
kq_fnmo_clean(kq_fnmo_p fnmo) {
566
567
	if (NULL == fnmo)
568
		return;
569
570
	kq_fnmo_rate_lim_stop(fnmo);
571
	if (-1 != fnmo->fd) {
572
		close(fnmo->fd);
573
		fnmo->fd = -1;
574
	}
575
	fnmo->is_removed ++;
576
577
	/* Stop monitoring files/dirs. */
578
	file_info_fd_close(fnmo->files, fnmo->files_count);
579
	free(fnmo->files);
580
	fnmo->files = NULL;
581
	fnmo->files_count = 0;
582
	fnmo->files_allocated = 0;
583
}
584
585
static void
586
kq_fnmo_free(kq_fnmo_p fnmo) {
587
588
	if (NULL == fnmo)
589
		return;
590
591
	kq_fnmo_clean(fnmo);
592
593
	if (0 != fnmo->is_cached &&
594
	    NULL != fnmo->kfnm &&
595
	    g_hash_table_lookup(fnmo->kfnm->fnmo_cache, fnmo->path) == fnmo) {
596
		g_hash_table_remove(fnmo->kfnm->fnmo_cache, fnmo->path);
597
	}
598
	free(fnmo);
599
}
600
601
static kq_fnmo_p
602
kq_fnmo_alloc(kq_fnm_p kfnm, const char *path, kq_fnme_p fnme) {
603
	kq_fnmo_p fnmo;
604
605
	if (NULL == kfnm || NULL == path)
606
		return (NULL);
607
	fnmo = zalloc(sizeof(kq_fnmo_t));
608
	if (NULL == fnmo)
609
		return (NULL);
610
	fnmo->fd = -1;
611
	/* Remember args. */
612
	fnmo->path_size = strlcpy(fnmo->path, path, PATH_MAX);
613
	/* Make sure that no trailing '/'. */
614
	while (1 < fnmo->path_size && '/' == fnmo->path[(fnmo->path_size - 1)]) {
615
		fnmo->path_size --;
616
		fnmo->path[fnmo->path_size] = 0;
617
	}
618
	/* Get parent folder name. */
619
	fnmo->name_offset = fnmo->path_size;
620
	while (0 < fnmo->name_offset && '/' != fnmo->path[(fnmo->name_offset - 1)]) {
621
		fnmo->name_offset --;
622
	}
623
	fnmo->kfnm = kfnm;
624
	TAILQ_INIT(&fnmo->entry_head);
625
	if (NULL != fnme) {
626
		TAILQ_INSERT_HEAD(&fnmo->entry_head, fnme, next);
627
	}
628
629
	return (fnmo);
630
}
631
632
static void
633
kq_fnmo_cb_func_call(kq_fnmo_p fnmo, uint32_t event,
634
    const char *base, const char *filename, const char *new_filename) {
635
	kq_fnm_p kfnm;
636
	kq_fnme_p fnme;
637
638
	if (NULL == fnmo)
639
		return;
640
	kfnm = fnmo->kfnm;
641
	TAILQ_FOREACH(fnme, &fnmo->entry_head, next) {
642
		if (0 == fnme->enabled) /* XXX: try lock here? */
643
			continue;
644
		kfnm->cb_func(kfnm, fnme, fnme->udata, event,
645
		    base, filename, new_filename);
646
	}
647
648
}
649
650
static int
651
kq_fnmo_readdir(kq_fnmo_p fnmo, size_t exp_count) {
652
	int error;
653
	struct dirent *de;
654
	file_info_p tmfi;
655
	readdir_ctx_t rdd;
656
657
	if (NULL == fnmo || -1 == fnmo->fd || 0 == fnmo->is_dir)
658
		return (EINVAL);
659
660
	free(fnmo->files);
661
	fnmo->files = NULL;
662
	fnmo->files_count = 0;
663
	fnmo->files_allocated = 0;
664
	/* Pre allocate. */
665
	if (0 != realloc_items((void**)&fnmo->files,
666
	    sizeof(file_info_t), &fnmo->files_allocated,
667
	    FILES_ALLOC_BLK_SIZE, (exp_count + 1)))
668
		return (ENOMEM);
669
670
	error = readdir_start(fnmo->fd, &fnmo->sb, exp_count, &rdd);
671
	if (0 != error)
672
		return (error);
673
	for (;;) {
674
		if (0 != realloc_items((void**)&fnmo->files,
675
		    sizeof(file_info_t), &fnmo->files_allocated,
676
		    FILES_ALLOC_BLK_SIZE, fnmo->files_count)) {
677
			free(fnmo->files);
678
			fnmo->files = NULL;
679
			fnmo->files_count = 0;
680
			fnmo->files_allocated = 0;
681
			readdir_free(&rdd);
682
			return (ENOMEM);
683
		}
684
		de = &fnmo->files[fnmo->files_count].de; /* Use short name. */
685
		/* Get file name from folder. */
686
		if (0 != readdir_next(&rdd, de))
687
			break;
688
		/* Get file attrs. */
689
		if (0 != fstatat(fnmo->fd, de->d_name,
690
		    &fnmo->files[fnmo->files_count].sb,
691
		    AT_SYMLINK_NOFOLLOW)) {
692
			if (ENOENT == errno)
693
				continue; /* File deleted. */
694
			memset(&fnmo->files[fnmo->files_count].sb, 0x00,
695
			    sizeof(struct stat));
696
		}
697
		fnmo->files[fnmo->files_count].fd = -1;
698
		fnmo->files_count ++;
699
	}
700
	/* Mem compact. */
701
	tmfi = reallocarray(fnmo->files, sizeof(file_info_t), (fnmo->files_count + 1));
702
	if (NULL != tmfi) { /* realloc ok. */
703
		fnmo->files = tmfi;
704
		fnmo->files_allocated = (fnmo->files_count + 1);
705
	}
706
707
	readdir_free(&rdd);
708
709
	return (0); /* OK. */
710
}
711
712
713
static void
714
kq_fnmo_fi_start(kq_fnmo_p fnmo, file_info_p fi) {
715
	struct kevent kev;
716
717
	if (NULL == fnmo || -1 == fnmo->fd || NULL == fi)
718
		return;
719
	fi->fd = openat(fnmo->fd, fi->de.d_name, OPEN_FILE_FLAGS);
720
	if (-1 == fi->fd)
721
		return;
722
	EV_SET(&kev, fi->fd, EVFILT_VNODE,
723
	    (EV_ADD | EV_CLEAR),
724
	    EVFILT_VNODE_SUB_FLAGS, 0, fnmo);
725
	kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL);
726
}
727
728
static int
729
kq_fnmo_is_fi_monitored(kq_fnmo_p fnmo, file_info_p fi) {
730
731
	if (NULL == fnmo)
732
		return (0);
733
	if (0 == fnmo->is_local ||
734
	    (0 != fnmo->kfnm->s.max_dir_files &&
735
	     fnmo->kfnm->s.max_dir_files < fnmo->files_count))
736
		return (0);
737
	if (NULL != fi &&
738
	    0 == fnmo->kfnm->s.mon_local_subdirs &&
739
	    S_ISDIR(fi->sb.st_mode))
740
		return (0);
741
	return (1);
742
}
743
744
static int
745
kq_fnmo_reopen_fd(kq_fnmo_p fnmo) {
746
	int error, fd;
747
	struct statfs stfs;
748
	struct kevent kev;
749
750
	if (NULL == fnmo)
751
		return (EINVAL);
752
753
	/* Close fd and stop timer. */
754
	kq_fnmo_rate_lim_stop(fnmo);
755
	if (-1 != fnmo->fd) {
756
		close(fnmo->fd);
757
		fnmo->fd = -1;
758
	}
759
760
	fd = open(fnmo->path, OPEN_FILE_FLAGS);
761
	if (-1 == fd)
762
		return (errno);
763
	if (0 != fstat(fd, &fnmo->sb)) {
764
		error = errno;
765
		goto err_out;
766
	}
767
	if (0 == fnmo->sb.st_nlink) {
768
		error = ENOENT;
769
		goto err_out;
770
	}
771
	if (S_ISDIR(fnmo->sb.st_mode)) {
772
		fnmo->is_dir = 1;
773
		/* Is file system local? */
774
		if (0 != fnmo->kfnm->s.mon_local_subfiles &&
775
		    0 == fstatfs(fd, &stfs)) {
776
			fnmo->is_local = is_fs_local(&stfs, fnmo->kfnm->s.local_fs,
777
			    fnmo->kfnm->s.non_local_fs);
778
		}
779
	}
780
781
	/* Add to kqueue. */
782
	EV_SET(&kev, fd, EVFILT_VNODE, (EV_ADD | EV_CLEAR),
783
	    EVFILT_VNODE_FLAGS_ALL, 0, fnmo);
784
	if (-1 == kevent(fnmo->kfnm->fd, &kev, 1, NULL, 0, NULL) ||
785
	    0 != (EV_ERROR & kev.flags)) {
786
		error = errno;
787
		goto err_out;
788
	}
789
790
	fnmo->is_removed = 0;
791
	fnmo->fd = fd;
792
793
	return (0); /* OK. */
794
795
err_out:
796
	close(fd);
797
	return (error);
798
}
799
800
static int
801
kq_fnmo_init(kq_fnmo_p fnmo) {
802
	int error;
803
	size_t i;
804
805
	if (NULL == fnmo)
806
		return (EINVAL);
807
808
	error = kq_fnmo_reopen_fd(fnmo);
809
	if (0 != error)
810
		goto err_out;
811
812
	if (0 == fnmo->is_dir)
813
		return (0); /* OK. */
814
	/* Dir special processing. */
815
816
	/* Read and remember dir content. */
817
	error = kq_fnmo_readdir(fnmo, 0);
818
	if (0 != error)
819
		goto err_out;
820
	/* Add monitor sub files/dirs, ignory errors. */
821
	/* Check twice for performance reason. */
822
	if (0 != kq_fnmo_is_fi_monitored(fnmo, NULL)) {
823
		for (i = 0; i < fnmo->files_count; i ++) {
824
			if (0 != kq_fnmo_is_fi_monitored(fnmo, &fnmo->files[i])) {
825
				kq_fnmo_fi_start(fnmo, &fnmo->files[i]);
826
			}
827
		}
828
	}
829
830
	return (0); /* OK. */
831
832
err_out:
833
	kq_fnmo_clean(fnmo);
834
	return (error);
835
}
836
837
static void
838
kq_fnme_init_cb(void *arg) {
839
	kq_fnme_p fnme = arg;
840
	kq_fnmo_p fnmo;
841
	kq_fnm_p kfnm;
842
843
	if (NULL == fnme || NULL == fnme->fnmo)
844
		return;
845
	kfnm = fnme->fnmo->kfnm;
846
	/* Is in cache? */
847
	fnmo = g_hash_table_lookup(kfnm->fnmo_cache, fnme->fnmo->path);
848
	if (NULL == fnmo) {
849
		/* Init and add to cache. */
850
		g_hash_table_insert(kfnm->fnmo_cache,
851
		    fnme->fnmo->path, fnme->fnmo);
852
		fnme->fnmo->is_cached ++;
853
		kq_fnmo_init(fnme->fnmo);
854
		return;
855
	}
856
	/* Found in cache, use it. */
857
	TAILQ_REMOVE(&fnme->fnmo->entry_head, fnme, next);
858
	kq_fnmo_free(fnme->fnmo);
859
	fnme->fnmo = fnmo;
860
	TAILQ_INSERT_HEAD(&fnmo->entry_head, fnme, next);
861
	if (-1 == fnmo->fd) {
862
		/* Re init existing, no notify. */
863
		kq_fnmo_init(fnme->fnmo);	
864
	}
865
}
866
867
static void
868
kq_fnme_free(kq_fnme_p fnme) {
869
870
	if (NULL == fnme)
871
		return;
872
	if (NULL != fnme->fnmo) {
873
		TAILQ_REMOVE(&fnme->fnmo->entry_head, fnme, next);
874
		if (TAILQ_EMPTY(&fnme->fnmo->entry_head)) {
875
			kq_fnmo_free(fnme->fnmo);
876
		}
877
	}
878
	free(fnme);
879
}
880
881
static void
882
kq_fnme_free_cb(void *arg) {
883
884
	kq_fnme_free((kq_fnme_p)arg);
885
}
886
887
888
static void
889
kq_handle_notify_removed(kq_fnmo_p fnmo) {
890
	size_t i;
891
892
	if (NULL == fnmo || 0 != fnmo->is_removed)
893
		return;
894
895
	if (0 != fnmo->is_dir) {
896
		/* Notify removed files first. */
897
		for (i = 0; i < fnmo->files_count; i ++) {
898
			kq_fnmo_cb_func_call(fnmo, KF_EVENT_DELETED,
899
			    fnmo->path, fnmo->files[i].de.d_name, NULL);
900
		}
901
	}
902
	fnmo->path[fnmo->name_offset - 1] = 0;
903
	kq_fnmo_cb_func_call(fnmo, KF_EVENT_DELETED, fnmo->path,
904
	    (fnmo->path + fnmo->name_offset), NULL);
905
	fnmo->path[fnmo->name_offset - 1] = '/';
906
	kq_fnmo_clean(fnmo);
907
}
908
909
static void
910
kq_handle_changes(kq_fnmo_p fnmo) {
911
	size_t i, k, files_count;
912
	file_info_p files;
913
914
	if (NULL == fnmo || -1 == fnmo->fd)
915
		return;
916
	if (0 != fstat(fnmo->fd, &fnmo->sb) ||
917
	    0 == fnmo->sb.st_nlink) {
918
		kq_handle_notify_removed(fnmo);
919
		return;
920
	}
921
	if (0 == fnmo->is_dir) {
922
		fnmo->path[fnmo->name_offset - 1] = 0;
923
		kq_fnmo_cb_func_call(fnmo, KF_EVENT_CHANGED, fnmo->path,
924
		    (fnmo->path + fnmo->name_offset), NULL);
925
		fnmo->path[fnmo->name_offset - 1] = '/';
926
		return;
927
	}
928
929
	/* Dir processing. */
930
931
	/* Save prev. */
932
	files = fnmo->files;
933
	files_count = fnmo->files_count;
934
	fnmo->files = NULL;
935
	fnmo->files_count = 0;
936
	/* Update dir. */
937
	if (0 != kq_fnmo_readdir(fnmo, files_count)) {
938
		/* Restore prev state on fail. */
939
		fnmo->files = files;
940
		fnmo->files_count = files_count;
941
		return;
942
	}
943
944
	/* Notify removed first. */
945
	for (i = 0; i < files_count; i ++) {
946
		if (0 != file_info_find_ni(fnmo->files, fnmo->files_count,
947
		    &files[i], &k)) /* Deleted? */
948
			continue;
949
		if (-1 != files[i].fd) {
950
			close(files[i].fd);
951
			files[i].fd = -1;
952
		}
953
		kq_fnmo_cb_func_call(fnmo, KF_EVENT_DELETED, fnmo->path,
954
		    files[i].de.d_name, NULL);
955
	}
956
	/* Notify. */
957
	for (i = 0; i < fnmo->files_count; i ++) {
958
		/* Is new file/folder? */
959
		if (0 == file_info_find_ino(files, files_count, &fnmo->files[i], &k) &&
960
		    0 == file_info_find_name(files, files_count, &fnmo->files[i], &k)) { /* Add new. */
961
			/* Add monitor sub files/dirs, ignory errors. */
962
			if (0 != kq_fnmo_is_fi_monitored(fnmo, &fnmo->files[i])) {
963
				kq_fnmo_fi_start(fnmo, &fnmo->files[i]);
964
			}
965
			kq_fnmo_cb_func_call(fnmo, KF_EVENT_CREATED,
966
			    fnmo->path, fnmo->files[i].de.d_name, NULL);
967
			continue;
968
		}
969
		/* Keep file fd. */
970
		fnmo->files[i].fd = files[k].fd;
971
		files[k].fd = -1;
972
		/* Is renamed? */
973
		if (0 == IS_DE_NAME_EQ(&files[k].de, &fnmo->files[i].de)) {
974
			kq_fnmo_cb_func_call(fnmo, KF_EVENT_RENAMED,
975
			    fnmo->path, files[k].de.d_name,
976
			    fnmo->files[i].de.d_name);
977
			continue;
978
		}
979
		/* Is modified? */
980
		if (0 != memcmp(&fnmo->files[i].sb, &files[k].sb, sizeof(struct stat))) {
981
			kq_fnmo_cb_func_call(fnmo, KF_EVENT_CHANGED,
982
			    fnmo->path, fnmo->files[i].de.d_name, NULL);
983
			continue;
984
		}
985
		/* Not changed. */
986
	}
987
988
	/* Prevent FD leak die to race conditions.
989
	 * All fd must be -1, check this while debuging.
990
	 */
991
	file_info_fd_close(files, files_count);
992
	free(files);
993
}
994
995
static int
996
kq_handle_rename(kq_fnmo_p fnmo) {
997
	int error, up_dir_fd, found = 0;
998
	readdir_ctx_t rdd;
999
	struct dirent de;
1000
	struct stat sb;
1001
	char old_filename[(MAXNAMLEN + sizeof(void*))];
1002
	size_t old_filename_size;
1003
1004
	if (NULL == fnmo || -1 == fnmo->fd)
1005
		return (EINVAL);
1006
	if (0 != fstat(fnmo->fd, &fnmo->sb) ||
1007
	    0 == fnmo->sb.st_nlink) {
1008
notify_removed_errno:
1009
		error = errno;
1010
notify_removed:
1011
		kq_handle_notify_removed(fnmo);
1012
		return (error);
1013
	}
1014
	/* Save old file name. */
1015
	old_filename_size = (fnmo->path_size - fnmo->name_offset);
1016
	memcpy(old_filename,
1017
	    (fnmo->path + fnmo->name_offset),
1018
	    old_filename_size);
1019
	old_filename[old_filename_size] = 0;
1020
1021
	/* Get parent folder name. */
1022
	fnmo->path[fnmo->name_offset] = 0;
1023
	/* Try to open. */
1024
	up_dir_fd = open(fnmo->path, (OPEN_FILE_FLAGS | O_DIRECTORY));
1025
	/* Restore '/' after parent folder. */
1026
	fnmo->path[fnmo->name_offset] = '/';
1027
	if (-1 == up_dir_fd)
1028
		goto notify_removed_errno;
1029
	if (0 != fstat(up_dir_fd, &sb)) {
1030
		close(up_dir_fd);
1031
		goto notify_removed_errno;
1032
	}
1033
	error = readdir_start(up_dir_fd, &sb, 0, &rdd);
1034
	if (0 != error) {
1035
		close(up_dir_fd);
1036
		goto notify_removed;
1037
	}
1038
	/* Find new name by inode. */
1039
	while (0 == readdir_next(&rdd, &de)) {
1040
		if (0 == fstatat(up_dir_fd, de.d_name, &sb, AT_SYMLINK_NOFOLLOW) &&
1041
		    0 == memcmp(&fnmo->sb, &sb, sizeof(struct stat))) {
1042
			found ++;
1043
			break;
1044
		}
1045
	}
1046
	close(up_dir_fd);
1047
	if (0 == found) {
1048
		error = ENOENT;
1049
		goto notify_removed; /* Not found. */
1050
	}
1051
	/* Update name. */
1052
	if (PATH_MAX < (fnmo->name_offset + de.d_namlen)) {
1053
		error = EINVAL;
1054
		goto notify_removed;
1055
	}
1056
	memcpy((fnmo->path + fnmo->name_offset), de.d_name, de.d_namlen);
1057
	fnmo->path_size = (fnmo->name_offset + de.d_namlen);
1058
	fnmo->path[fnmo->path_size] = 0;
1059
	/* Notify. */
1060
	kq_fnmo_cb_func_call(fnmo, KF_EVENT_RENAMED, fnmo->path,
1061
	    old_filename, de.d_name);
1062
1063
	return (0);
1064
}
1065
1066
1067
static void
1068
kq_fnm_delay_call_process(kq_fnm_p kfnm, kq_msg_cb forced_msg_cb) {
1069
	ssize_t ios;
1070
	kq_fnm_msg_pkt_t msg;
1071
1072
	for (;;) {
1073
		ios = read(kfnm->pfd[0], &msg, sizeof(msg));
1074
		if (0 >= ios)
1075
			return;
1076
		if (sizeof(msg) != ios ||
1077
		    KF_MSG_PKT_MAGIC != msg.magic ||
1078
		    (((size_t)msg.msg_cb) ^ ((size_t)msg.arg)) != msg.chk_sum)
1079
			continue;
1080
		if (NULL != forced_msg_cb) {
1081
			forced_msg_cb(msg.arg);
1082
			continue;
1083
		}
1084
		if (NULL == msg.msg_cb)
1085
			continue;
1086
		msg.msg_cb(msg.arg);
1087
	}
1088
}
1089
1090
static int
1091
kq_fnm_delay_call(kq_fnm_p kfnm, kq_msg_cb msg_cb,
1092
    void *arg) {
1093
	kq_fnm_msg_pkt_t msg;
1094
1095
	if (NULL == kfnm || NULL == arg)
1096
		return (EINVAL);
1097
	msg.magic = KF_MSG_PKT_MAGIC;
1098
	msg.msg_cb = msg_cb;
1099
	msg.arg = arg;
1100
	msg.chk_sum = (((size_t)msg.msg_cb) ^ ((size_t)msg.arg));
1101
	if (sizeof(msg) == write(kfnm->pfd[1], &msg, sizeof(msg)))
1102
		return (0);
1103
	return (errno);
1104
}
1105
1106
1107
static void
1108
kq_fnm_free_cb(void *arg) {
1109
	kq_fnm_p kfnm = arg;
1110
1111
	if (NULL == kfnm)
1112
		return;
1113
	close(kfnm->fd);
1114
	kfnm->fd = -1;
1115
}
1116
void
1117
kq_fnm_free(kq_fnm_p kfnm) {
1118
	GHashTableIter iter;
1119
	gpointer key;
1120
	kq_fnmo_p fnmo;
1121
	kq_fnme_p fnme, fnme_temp;
1122
1123
	if (NULL == kfnm)
1124
		return;
1125
	kq_fnm_delay_call(kfnm, kq_fnm_free_cb, kfnm);
1126
	pthread_join(kfnm->tid, NULL);
1127
	/* Free all in delay calls queue. */
1128
	close(kfnm->pfd[1]);
1129
	kq_fnm_delay_call_process(kfnm, kq_fnme_free_cb);
1130
	close(kfnm->pfd[0]);
1131
	/* Remove all objects. */
1132
	g_hash_table_iter_init(&iter, kfnm->fnmo_cache);
1133
	while (g_hash_table_iter_next(&iter, &key, (gpointer)&fnmo)) {
1134
		TAILQ_FOREACH_SAFE(fnme, &fnmo->entry_head, next, fnme_temp) {
1135
			TAILQ_REMOVE(&fnmo->entry_head, fnme, next);
1136
			fnme->fnmo = NULL; /* Do not free fnmo here. */
1137
			kq_fnme_free(fnme);
1138
		}
1139
		g_hash_table_iter_remove(&iter); /* Remove from cache here. */
1140
		/* Prevent remove from cache or g_hash_table_iter_next() will fail. */
1141
		fnmo->is_cached = 0;
1142
		kq_fnmo_free(fnmo);
1143
	}
1144
	g_hash_table_destroy(kfnm->fnmo_cache);
1145
1146
	free(kfnm->mounts);
1147
	free(kfnm);
1148
}
1149
1150
kq_fnm_p
1151
kq_fnm_create(kq_file_mon_settings_p s, kfnm_event_handler_cb cb_func) {
1152
	kq_fnm_p kfnm;
1153
	struct kevent kev;
1154
1155
	if (NULL == s || NULL == cb_func)
1156
		return (NULL);
1157
	kfnm = zalloc(sizeof(kq_fnm_t));
1158
	if (NULL == kfnm)
1159
		return (NULL);
1160
	kfnm->fd = kqueue();
1161
	if (-1 == kfnm->fd)
1162
		goto err_out;
1163
	if (-1 == pipe2(kfnm->pfd, O_NONBLOCK))
1164
		goto err_out;
1165
	kfnm->fnmo_cache = g_hash_table_new(g_str_hash, g_str_equal);
1166
	kfnm->cb_func = cb_func;
1167
	memcpy(&kfnm->s, s, sizeof(kq_file_mon_settings_t));
1168
	if (kfnm->s.rate_limit_time_init >= kfnm->s.rate_limit_time_max) {
1169
		kfnm->s.rate_limit_time_max = kfnm->s.rate_limit_time_init;
1170
	}
1171
	if (0 == kfnm->s.rate_limit_time_mul) {
1172
		kfnm->s.rate_limit_time_mul ++;
1173
	}
1174
	kfnm->rate_lim_time_init = MSTOSBT(kfnm->s.rate_limit_time_init);
1175
1176
	EV_SET(&kev, kfnm->pfd[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
1177
	if (-1 == kevent(kfnm->fd, &kev, 1, NULL, 0, NULL) ||
1178
	    0 != (EV_ERROR & kev.flags))
1179
		goto err_out;
1180
	EV_SET(&kev, 0, EVFILT_FS, EV_ADD, 0, 0, NULL);
1181
	if (-1 == kevent(kfnm->fd, &kev, 1, NULL, 0, NULL) ||
1182
	    0 != (EV_ERROR & kev.flags))
1183
		goto err_out;
1184
	/* Get initial mounts points. */
1185
	kfnm->mounts_count = (size_t)getmntinfo_ex(&kfnm->mounts, MNT_WAIT);
1186
1187
	if (0 != pthread_create(&kfnm->tid, NULL,
1188
	    kq_fnm_proccess_events_proc, kfnm))
1189
		goto err_out;
1190
1191
	return (kfnm);
1192
1193
err_out:
1194
	kq_fnm_free(kfnm);
1195
	return (NULL);
1196
}
1197
1198
kq_fnme_p
1199
kq_fnm_add(kq_fnm_p kfnm, const char *path, void *udata) {
1200
	int error;
1201
	kq_fnme_p fnme;
1202
1203
	if (NULL == kfnm || NULL == path)
1204
		return (NULL);
1205
	fnme = zalloc(sizeof(kq_fnme_t));
1206
	if (NULL == fnme)
1207
		return (NULL);
1208
	fnme->fnmo = kq_fnmo_alloc(kfnm, path, fnme);
1209
	if (NULL == fnme->fnmo)
1210
		goto err_out;
1211
	fnme->udata = udata;
1212
	fnme->enabled = 1;
1213
	/* Shedule delay call to init. */
1214
	error = kq_fnm_delay_call(kfnm, kq_fnme_init_cb, fnme);
1215
	if (0 != error) { /* Error, do no directly init to avoid freezes. */
1216
		kq_fnmo_free(fnme->fnmo);
1217
err_out:
1218
		fnme->fnmo = NULL;
1219
		kq_fnme_free(fnme);
1220
		return (NULL);
1221
	}
1222
	return (fnme);
1223
}
1224
1225
void
1226
kq_fnm_del(kq_fnm_p kfnm, kq_fnme_p fnme) {
1227
	int error;
1228
1229
	if (NULL == kfnm || NULL == fnme)
1230
		return;
1231
	/* Cancel notifications. */
1232
	/* XXX: lock here? */
1233
	fnme->enabled = 0;
1234
	/* Shedule delay call to free. */
1235
	error = kq_fnm_delay_call(kfnm, kq_fnme_free_cb, fnme);
1236
	if (0 == error)
1237
		return;
1238
	/* Error, free directly. */
1239
	kq_fnme_free(fnme);
1240
}
1241
1242
1243
static void
1244
kq_fnm_handle_mnt_point_change(kq_fnm_p kfnm, const char *mntonname) {
1245
	int error;
1246
	GHashTableIter iter;
1247
	gpointer key;
1248
	kq_fnmo_p fnmo;
1249
	size_t mntonname_size;
1250
1251
	if (NULL == kfnm || NULL == mntonname || 0 == mntonname[0])
1252
		return;
1253
	mntonname_size = strnlen(mntonname, MNAMELEN);
1254
	/* Remove all objects. */
1255
	g_hash_table_iter_init(&iter, kfnm->fnmo_cache);
1256
	while (g_hash_table_iter_next(&iter, &key, (gpointer)&fnmo)) {
1257
		if (NULL == fnmo || -1 == fnmo->fd) /* Do not reopen deleted. */
1258
			continue;
1259
		if (mntonname_size > fnmo->path_size)
1260
			continue;
1261
		if (0 != memcmp(fnmo->path, mntonname, mntonname_size))
1262
			continue;
1263
		/* Try to reopen mount point after unmount. */
1264
		error = kq_fnmo_reopen_fd(fnmo);
1265
		if (0 != error) {
1266
			kq_handle_notify_removed(fnmo);
1267
			continue;
1268
		}
1269
		/* Reread dir and notify about deleted and new files. */
1270
		kq_handle_changes(fnmo);
1271
	}
1272
}
1273
static void
1274
kq_handle_mount_changes(kq_fnm_p kfnm) {
1275
	size_t i, mounts_count;
1276
	struct statfs *mounts;
1277
1278
	if (NULL == kfnm)
1279
		return;
1280
1281
	/* Save prev. */
1282
	mounts = kfnm->mounts;
1283
	mounts_count = kfnm->mounts_count;
1284
	kfnm->mounts = NULL;
1285
	kfnm->mounts_count = (size_t)getmntinfo_ex(&kfnm->mounts, MNT_WAIT);
1286
1287
	/* Removed mounts. */
1288
	for (i = 0; i < mounts_count; i ++) {
1289
		if (0 != mounts_find_name(kfnm->mounts, kfnm->mounts_count,
1290
		    mounts[i].f_mntonname))
1291
			continue;
1292
		kq_fnm_handle_mnt_point_change(kfnm, mounts[i].f_mntonname);
1293
	}
1294
	/* New mounts. */
1295
	for (i = 0; i < kfnm->mounts_count; i ++) {
1296
		if (0 != mounts_find_name(mounts, mounts_count,
1297
		    kfnm->mounts[i].f_mntonname))
1298
			continue;
1299
		kq_fnm_handle_mnt_point_change(kfnm, kfnm->mounts[i].f_mntonname);
1300
	}
1301
1302
	/* Free old mounts. */
1303
	free(mounts);
1304
}
1305
1306
1307
static void
1308
kq_fnm_proccess_event(kq_fnm_p kfnm, struct kevent *kev) {
1309
	int error;
1310
	kq_fnmo_p fnmo;
1311
	file_info_p fi;
1312
	size_t i;
1313
	int is_rate_lim_checked = 0;
1314
	struct stat sb;
1315
1316
	if (NULL == kfnm || NULL == kev)
1317
		return;
1318
1319
	/* Handle delay calls. */
1320
	if (kev->ident == (uintptr_t)kfnm->pfd[0]) {
1321
		if (EVFILT_READ == kev->filter) {
1322
			kq_fnm_delay_call_process(kfnm, NULL);
1323
		}
1324
		return;
1325
	}
1326
1327
	/* Handle mount/unmount events. */
1328
	if (EVFILT_FS == kev->filter) {
1329
		kq_handle_mount_changes(kfnm);
1330
		return;
1331
	}
1332
1333
	if (0 == kev->udata)
1334
		return; /* No associated data, skip. */
1335
	fnmo = (kq_fnmo_p)kev->udata;
1336
1337
	/* FS delayed notifications. */
1338
	if (EVFILT_TIMER == kev->filter) {
1339
		if (0 == fnmo->rate_lim_ev_cnt) {
1340
			/* No delayed events, disable rate limit polling. */
1341
			kq_fnmo_rate_lim_stop(fnmo);
1342
			return;
1343
		}
1344
		fnmo->rate_lim_ev_cnt = 0; /* Reset counter. */
1345
		kq_fnmo_rate_lim_shedule_next(fnmo);
1346
		kq_handle_changes(fnmo);
1347
		return;
1348
	}
1349
1350
	/* FS notifications. */
1351
	if (EVFILT_VNODE != kev->filter)
1352
		return; /* Unknown event, skip. */
1353
	/* Subdir/file */
1354
	if (kev->ident != (uintptr_t)fnmo->fd) {
1355
		/* Is files changes rate limited? */
1356
		if (1 == kq_fnmo_rate_lim_check(fnmo))
1357
			return;
1358
		is_rate_lim_checked ++;
1359
		/* Try to find file and check it, without call kq_handle_changes(). */
1360
		fi = NULL;
1361
		for (i = 0; i < fnmo->files_count; i ++) {
1362
			if (kev->ident != (uintptr_t)fnmo->files[i].fd)
1363
				continue;
1364
			fi = &fnmo->files[i];
1365
			break;
1366
		}
1367
		if (NULL != fi) {
1368
			/* Get file attrs. */
1369
			if (0 != fstat(fi->fd, &sb)) {
1370
				memset(&sb, 0x00, sizeof(struct stat));
1371
			}
1372
			/* Is modified? */
1373
			if (0 != memcmp(&fi->sb, &sb, sizeof(struct stat))) {
1374
				memcpy(&fi->sb, &sb, sizeof(struct stat));
1375
				kq_fnmo_cb_func_call(fnmo, KF_EVENT_CHANGED,
1376
				    fnmo->path, fi->de.d_name, NULL);
1377
				return;
1378
			}
1379
		}
1380
		/* fd not found or changes not found, rescan dir. */
1381
		kev->fflags = NOTE_WRITE;
1382
	}
1383
	/* Monitored object. */
1384
	/* All flags from EVFILT_VNODE_FLAGS_ALL must be handled here. */
1385
	if (EV_ERROR & kev->flags) {
1386
		kev->fflags |= NOTE_REVOKE; /* Treat error as unmount. */
1387
	}
1388
	if ((NOTE_DELETE | NOTE_REVOKE) & kev->fflags) {
1389
		/* No ratelimit here. */
1390
		if (0 != fnmo->is_dir) {
1391
			/* Try to reopen mount point after unmount. */
1392
			error = kq_fnmo_reopen_fd(fnmo);
1393
			if (0 == error) {
1394
				/* This will reread dir and notify about
1395
				 * deleted and new files. */
1396
				kq_handle_changes(fnmo);
1397
			}
1398
		} else {
1399
			error = -1;
1400
		}
1401
		if (0 != error) {
1402
			kq_handle_notify_removed(fnmo);
1403
		}
1404
		return; /* All events processed. */
1405
	}
1406
	if (NOTE_RENAME & kev->fflags) {
1407
		error = kq_handle_rename(fnmo);
1408
		if (0 != error)
1409
			return;
1410
	}
1411
	if ((NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_CLOSE_WRITE) & kev->fflags) {
1412
		if (0 == is_rate_lim_checked &&
1413
		    1 != kq_fnmo_rate_lim_check(fnmo)) {
1414
			kq_handle_changes(fnmo);
1415
		}
1416
	}
1417
}
1418
1419
void *
1420
kq_fnm_proccess_events_proc(void *data) {
1421
	struct kevent kev;
1422
	kq_fnm_p kfnm = data;
1423
1424
	if (NULL == kfnm)
1425
		return (NULL);
1426
	/* Get and proccess events, no wait. */
1427
	while (0 < kevent(kfnm->fd, NULL, 0, &kev, 1, NULL)) {
1428
		kq_fnm_proccess_event(kfnm, &kev);
1429
	}
1430
	return (NULL);
1431
}
(-)devel/glib20/files/kqueue_fnm.h (+74 lines)
Line 0 Link Here
1
/*-
2
 * Copyright (c) 2016 - 2019 Rozhuk Ivan <rozhuk.im@gmail.com>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 *
26
 * Author: Rozhuk Ivan <rozhuk.im@gmail.com>
27
 *
28
 */
29
30
#ifndef __KQUEUE_FILE_NOTIFY_MONITOR_H__
31
#define __KQUEUE_FILE_NOTIFY_MONITOR_H__
32
33
#include <sys/param.h>
34
#include <sys/types.h>
35
#include <inttypes.h>
36
37
38
typedef struct kq_file_nonify_monitor_s		*kq_fnm_p;
39
typedef struct kq_file_nonify_monitor_entry_s	*kq_fnme_p;
40
41
typedef void (*kfnm_event_handler_cb)(kq_fnm_p kfnm,
42
					kq_fnme_p fnme, void *udata,
43
					uint32_t event,
44
					const char *base,
45
					const char *filename,
46
					const char *new_filename);
47
#define KF_EVENT_NOT_CHANGED	0 /* Internal use. */
48
#define KF_EVENT_CREATED	1
49
#define KF_EVENT_DELETED	2
50
#define KF_EVENT_RENAMED	3
51
#define KF_EVENT_CHANGED	4
52
53
54
typedef struct kq_file_nonify_mon_settings_s {
55
	uint32_t	rate_limit_time_init;	/* Fire events for dir min interval, mseconds. */
56
	uint32_t	rate_limit_time_max;	/* Fire events for dir max interval, mseconds. */
57
	uint32_t	rate_limit_time_mul;	/* Fire events time increment, mseconds. */
58
	size_t		max_dir_files;		/* If dir contain more than n files - do not mon files changes. */
59
	int		mon_local_subfiles;	/* Enable monitoring files changes on local file systems. */
60
	int		mon_local_subdirs;	/* Also mon for subdirs changes . */
61
	const char 	**local_fs;		/* NULL terminated fs names list that threat as local. Keep utill kq_fnm_free() return. */
62
	const char	**non_local_fs;		/* NULL terminated fs names list that threat as not local. Keep utill kq_fnm_free() return. */
63
} kq_file_mon_settings_t, *kq_file_mon_settings_p;
64
65
kq_fnm_p	kq_fnm_create(kq_file_mon_settings_p s,
66
		    kfnm_event_handler_cb cb_func);
67
void		kq_fnm_free(kq_fnm_p kfnm);
68
69
kq_fnme_p	kq_fnm_add(kq_fnm_p kfnm,
70
			    const char *path, void *udata);
71
void		kq_fnm_del(kq_fnm_p kfnm, kq_fnme_p fnme);
72
73
74
#endif /* __KQUEUE_FILE_NOTIFY_MONITOR_H__ */

Return to bug 214338