mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2025-03-01 08:47:24 +00:00
vnode fixes, build fixes.
unit tests run under linux and openbsd. last checkin before 0.1 branch git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@45 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
parent
e49207038b
commit
12fc5329ce
1
Makefile
1
Makefile
@ -17,7 +17,6 @@ PROGRAM=libkqueue
|
||||
INSTALL=/usr/bin/install
|
||||
DISTFILES=*.c *.h kqueue.2 README Makefile configure os sys
|
||||
SOURCES=src/$(UNAME)/*.c
|
||||
CFLAGS=-fPIC -D_REENTRANT -I. -Wall -Werror -fvisibility=hidden
|
||||
FILTERS=vnode.c timer.c signal.c socket.c user.c
|
||||
|
||||
include config.mk
|
||||
|
20
configure
vendored
20
configure
vendored
@ -4,12 +4,12 @@ program=libkqueue
|
||||
version=0.1
|
||||
|
||||
finalize() {
|
||||
eval "if [ \"\$$1\" = \"\" ] ; then $1=$2 ; fi"
|
||||
eval "if [ \"\$$1\" = \"\" ] ; then $1=\"$2\" ; fi"
|
||||
|
||||
# Add the variable to config.mk and config.h
|
||||
id=`echo $1 | tr 'a-z' 'A-Z'`;
|
||||
eval "echo \"$id=\$$1\" >> config.mk"
|
||||
eval "echo \"#define $id \\\"\$$1\\\"\" >> config.h"
|
||||
uc_id=`echo $1 | tr 'a-z' 'A-Z'`;
|
||||
eval "echo \"$uc_id=\"\$$1\"\" >> config.mk"
|
||||
eval "echo \"#define $uc_id \\\"\$$1\\\"\" >> config.h"
|
||||
}
|
||||
|
||||
process_argv() {
|
||||
@ -44,16 +44,25 @@ check_header() {
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
default_cflags="-fPIC -D_REENTRANT -I. -Wall -Werror"
|
||||
|
||||
# Initialize the output files
|
||||
#
|
||||
for output_file in config.h config.mk $program.pc
|
||||
for output_file in config.mk $program.pc
|
||||
do
|
||||
rm -f $output_file
|
||||
echo "# AUTOMATICALLY GENERATED -- DO NOT EDIT" > $output_file
|
||||
done
|
||||
rm -f config.h
|
||||
echo "/* AUTOMATICALLY GENERATED -- DO NOT EDIT */" > config.h
|
||||
|
||||
process_argv $*
|
||||
|
||||
if [ "$debug" = "yes" ]
|
||||
then
|
||||
default_cflags="$default_cflags -DKQUEUE_DEBUG"
|
||||
fi
|
||||
|
||||
finalize program $program
|
||||
finalize version $version
|
||||
finalize target `uname -s | tr A-Z a-z`
|
||||
@ -61,6 +70,7 @@ finalize prefix /usr/local
|
||||
finalize libdir "${prefix}/lib"
|
||||
finalize includedir "${prefix}/include"
|
||||
finalize mandir "${prefix}/share/man"
|
||||
finalize cflags "$default_cflags"
|
||||
|
||||
echo "Checking operating system type... $target"
|
||||
rm -f socket.c vnode.c signal.c timer.c user.c
|
||||
|
@ -119,7 +119,7 @@ evfilt_signal_copyout(struct filter *filt,
|
||||
dst->ident = sig[i].ssi_signo;
|
||||
dst->filter = EVFILT_SIGNAL;
|
||||
dst->udata = kn->kev.udata;
|
||||
dst->flags = 0;
|
||||
dst->flags = EV_ADD | EV_CLEAR;
|
||||
dst->fflags = 0;
|
||||
dst->data = 1;
|
||||
|
||||
@ -129,8 +129,10 @@ evfilt_signal_copyout(struct filter *filt,
|
||||
}
|
||||
if (kn->kev.flags & EV_DISPATCH)
|
||||
KNOTE_DISABLE(kn);
|
||||
if (kn->kev.flags & EV_ONESHOT)
|
||||
if (kn->kev.flags & EV_ONESHOT) {
|
||||
dst->flags |= EV_ONESHOT;
|
||||
knote_free(kn);
|
||||
}
|
||||
|
||||
dst++;
|
||||
nevents++;
|
||||
|
@ -178,8 +178,12 @@ evfilt_socket_copyout(struct filter *filt,
|
||||
dst->ident = kn->kev.ident;
|
||||
dst->filter = kn->kev.filter;
|
||||
dst->udata = kn->kev.udata;
|
||||
dst->flags = 0;
|
||||
dst->flags = EV_ADD;
|
||||
dst->fflags = 0;
|
||||
if (kn->kev.flags & EV_ONESHOT) /*TODO: move elsewhere */
|
||||
dst->flags |= EV_ONESHOT;
|
||||
if (kn->kev.flags & EV_CLEAR) /*TODO: move elsewhere */
|
||||
dst->flags |= EV_CLEAR;
|
||||
if (ev->events & EPOLLRDHUP || ev->events & EPOLLHUP)
|
||||
dst->flags |= EV_EOF;
|
||||
if (ev->events & EPOLLERR)
|
||||
|
@ -35,16 +35,18 @@
|
||||
#include "sys/event.h"
|
||||
#include "private.h"
|
||||
|
||||
#define INEVT_MASK_DUMP(attrib) \
|
||||
if (evt->mask & attrib) \
|
||||
fputs(#attrib, stdout);
|
||||
|
||||
static void
|
||||
inotify_event_dump(struct inotify_event *evt)
|
||||
char *
|
||||
inotify_mask_dump(uint32_t mask)
|
||||
{
|
||||
fputs("[BEGIN: inotify_event dump]\n", stdout);
|
||||
fprintf(stdout, " wd = %d\n", evt->wd);
|
||||
fprintf(stdout, " mask = %o (", evt->mask);
|
||||
char *buf;
|
||||
|
||||
#define INEVT_MASK_DUMP(attrib) \
|
||||
if (mask & attrib) \
|
||||
strcat(buf, #attrib" ");
|
||||
|
||||
if ((buf = calloc(1, 1024)) == NULL)
|
||||
abort();
|
||||
sprintf(buf, "mask = %d (", mask);
|
||||
INEVT_MASK_DUMP(IN_ACCESS);
|
||||
INEVT_MASK_DUMP(IN_MODIFY);
|
||||
INEVT_MASK_DUMP(IN_ATTRIB);
|
||||
@ -57,6 +59,18 @@ inotify_event_dump(struct inotify_event *evt)
|
||||
INEVT_MASK_DUMP(IN_DELETE);
|
||||
INEVT_MASK_DUMP(IN_DELETE_SELF);
|
||||
INEVT_MASK_DUMP(IN_MOVE_SELF);
|
||||
buf[strlen(buf) - 1] = ')';
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
inotify_event_dump(struct inotify_event *evt)
|
||||
{
|
||||
fputs("[BEGIN: inotify_event dump]\n", stdout);
|
||||
fprintf(stdout, " wd = %d\n", evt->wd);
|
||||
fprintf(stdout, " %s", inotify_mask_dump(evt->mask));
|
||||
|
||||
fputs(")\n", stdout);
|
||||
fputs("[END: inotify_event dump]\n", stdout);
|
||||
fflush(stdout);
|
||||
@ -140,6 +154,7 @@ evfilt_vnode_copyin(struct filter *filt,
|
||||
struct knote *dst, const struct kevent *src)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct stat sb;
|
||||
uint32_t mask;
|
||||
|
||||
if (src->flags & EV_DELETE || src->flags & EV_DISABLE)
|
||||
@ -147,7 +162,12 @@ evfilt_vnode_copyin(struct filter *filt,
|
||||
|
||||
if (src->flags & EV_ADD && KNOTE_EMPTY(dst)) {
|
||||
memcpy(&dst->kev, src, sizeof(*src));
|
||||
dst->kev.flags |= EV_CLEAR;
|
||||
if (fstat(src->ident, &sb) < 0) {
|
||||
dbg_puts("fstat failed");
|
||||
return (-1);
|
||||
}
|
||||
dst->kn_st_nlink = sb.st_nlink;
|
||||
dst->kn_st_size = sb.st_size;
|
||||
dst->kev.data = -1;
|
||||
}
|
||||
|
||||
@ -160,18 +180,21 @@ evfilt_vnode_copyin(struct filter *filt,
|
||||
/* Convert the fflags to the inotify mask */
|
||||
mask = 0;
|
||||
if (dst->kev.fflags & NOTE_DELETE)
|
||||
mask |= IN_DELETE_SELF;
|
||||
if (dst->kev.fflags & NOTE_WRITE)
|
||||
mask |= IN_MODIFY;
|
||||
if (dst->kev.fflags & NOTE_ATTRIB)
|
||||
mask |= IN_ATTRIB | IN_DELETE_SELF;
|
||||
if (dst->kev.fflags & NOTE_WRITE)
|
||||
mask |= IN_MODIFY | IN_ATTRIB;
|
||||
if (dst->kev.fflags & NOTE_EXTEND)
|
||||
mask |= IN_MODIFY | IN_ATTRIB;
|
||||
if ((dst->kev.fflags & NOTE_ATTRIB) ||
|
||||
(dst->kev.fflags & NOTE_LINK))
|
||||
mask |= IN_ATTRIB;
|
||||
if (dst->kev.fflags & NOTE_RENAME)
|
||||
mask |= IN_MOVE_SELF;
|
||||
if (dst->kev.flags & EV_ONESHOT)
|
||||
mask |= IN_ONESHOT;
|
||||
|
||||
dbg_printf("inotify_add_watch(2); inofd=%d, mask=%d, path=%s",
|
||||
filt->kf_pfd, mask, path);
|
||||
dbg_printf("inotify_add_watch(2); inofd=%d, %s, path=%s",
|
||||
filt->kf_pfd, inotify_mask_dump(mask), path);
|
||||
dst->kev.data = inotify_add_watch(filt->kf_pfd, path, mask);
|
||||
if (dst->kev.data < 0) {
|
||||
dbg_printf("inotify_add_watch(2): %s", strerror(errno));
|
||||
@ -188,6 +211,7 @@ evfilt_vnode_copyout(struct filter *filt,
|
||||
int nevents)
|
||||
{
|
||||
struct inotify_event evt;
|
||||
struct stat sb;
|
||||
struct knote *kn;
|
||||
|
||||
if (get_one_event(&evt, filt->kf_pfd) < 0)
|
||||
@ -209,9 +233,48 @@ evfilt_vnode_copyout(struct filter *filt,
|
||||
dst->ident = kn->kev.ident;
|
||||
dst->filter = kn->kev.filter;
|
||||
dst->udata = kn->kev.udata;
|
||||
dst->flags = 0;
|
||||
dst->flags = kn->kev.flags;
|
||||
dst->fflags = 0;
|
||||
|
||||
/* No error checking because fstat(2) should rarely fail */
|
||||
if ((evt.mask & IN_ATTRIB || evt.mask & IN_MODIFY)
|
||||
&& fstat(kn->kev.ident, &sb) == 0) {
|
||||
if (sb.st_nlink == 0 && kn->kev.fflags & NOTE_DELETE)
|
||||
dst->fflags |= NOTE_DELETE;
|
||||
if (sb.st_nlink != kn->kn_st_nlink && kn->kev.fflags & NOTE_LINK)
|
||||
dst->fflags |= NOTE_LINK;
|
||||
#if HAVE_NOTE_TRUNCATE
|
||||
if (sb.st_nsize == 0 && kn->kev.fflags & NOTE_TRUNCATE)
|
||||
dst->fflags |= NOTE_TRUNCATE;
|
||||
#endif
|
||||
if (sb.st_size > kn->kn_st_size && kn->kev.fflags & NOTE_WRITE)
|
||||
dst->fflags |= NOTE_EXTEND;
|
||||
kn->kn_st_nlink = sb.st_nlink;
|
||||
kn->kn_st_size = sb.st_size;
|
||||
}
|
||||
|
||||
if (evt.mask & IN_MODIFY && kn->kev.fflags & NOTE_WRITE)
|
||||
dst->fflags |= NOTE_WRITE;
|
||||
if (evt.mask & IN_ATTRIB && kn->kev.fflags & NOTE_ATTRIB)
|
||||
dst->fflags |= NOTE_ATTRIB;
|
||||
if (evt.mask & IN_MOVE_SELF && kn->kev.fflags & NOTE_RENAME)
|
||||
dst->fflags |= NOTE_RENAME;
|
||||
if (evt.mask & IN_DELETE_SELF && kn->kev.fflags & NOTE_DELETE)
|
||||
dst->fflags |= NOTE_DELETE;
|
||||
|
||||
if (kn->kev.flags & EV_DISPATCH) {
|
||||
delete_watch(filt->kf_pfd, kn); /* TODO: error checking */
|
||||
KNOTE_DISABLE(kn);
|
||||
#if HAVE_NOTE_TRUNCATE
|
||||
if (sb.st_size == 0 && kn->kev.fflags & NOTE_TRUNCATE)
|
||||
dst->fflags |= NOTE_TRUNCATE;
|
||||
#endif
|
||||
if (sb.st_size > kn->kn_st_size && kn->kev.fflags & NOTE_WRITE)
|
||||
dst->fflags |= NOTE_EXTEND;
|
||||
kn->kn_st_nlink = sb.st_nlink;
|
||||
kn->kn_st_size = sb.st_size;
|
||||
}
|
||||
|
||||
if (evt.mask & IN_MODIFY && kn->kev.fflags & NOTE_WRITE)
|
||||
dst->fflags |= NOTE_WRITE;
|
||||
if (evt.mask & IN_ATTRIB && kn->kev.fflags & NOTE_ATTRIB)
|
||||
|
@ -38,9 +38,14 @@ struct kqueue;
|
||||
struct kevent;
|
||||
struct evfilt_data;
|
||||
|
||||
/* TODO: Make this a variable length structure and allow
|
||||
each filter to add custom fields at the end.
|
||||
*/
|
||||
struct knote {
|
||||
struct kevent kev;
|
||||
int kn_pfd; /* Used by timerfd */
|
||||
nlink_t kn_st_nlink; /* Used by vnode */
|
||||
off_t kn_st_size; /* Used by vnode */
|
||||
LIST_ENTRY(knote) entries;
|
||||
};
|
||||
LIST_HEAD(knotelist, knote);
|
||||
|
@ -122,10 +122,8 @@ struct kevent {
|
||||
#define NOTE_DELETE 0x0001 /* vnode was removed */
|
||||
#define NOTE_WRITE 0x0002 /* data contents changed */
|
||||
#define NOTE_EXTEND 0x0004 /* size increased */
|
||||
#undef NOTE_EXTEND /* Not supported on Linux */
|
||||
#define NOTE_ATTRIB 0x0008 /* attributes changed */
|
||||
#define NOTE_LINK 0x0010 /* link count changed */
|
||||
#undef NOTE_LINK /* Not supported on Linux */
|
||||
#define NOTE_RENAME 0x0020 /* vnode was renamed */
|
||||
#define NOTE_REVOKE 0x0040 /* vnode access was revoked */
|
||||
#undef NOTE_REVOKE /* Not supported on Linux */
|
||||
|
@ -16,14 +16,13 @@
|
||||
|
||||
include config.mk
|
||||
|
||||
all:
|
||||
gcc $(CFLAGS) main.c read.c signal.c vnode.c timer.c $(LDADD)
|
||||
./a.out
|
||||
SOURCES=main.c read.c signal.c vnode.c timer.c
|
||||
|
||||
check:
|
||||
cd .. && make build CFLAGS="$(CFLAGS) -g -O0 -DKQUEUE_DEBUG -DUNIT_TEST"
|
||||
gcc -c $(CFLAGS) test.c
|
||||
gcc $(CFLAGS) test.c libkqueue.a $(LDADD)
|
||||
if [ ! -f /usr/include/sys/event.h ] ; then \
|
||||
cd .. && ./configure --debug=yes && make build ; \
|
||||
fi
|
||||
gcc $(CFLAGS) $(SOURCES) $(LDADD)
|
||||
./a.out
|
||||
|
||||
# NOTE: copy+paste of 'make check'
|
||||
|
12
test/main.c
12
test/main.c
@ -83,12 +83,16 @@ kevent_fflags_dump(struct kevent *kev)
|
||||
KEVFFL_DUMP(NOTE_DELETE);
|
||||
KEVFFL_DUMP(NOTE_WRITE);
|
||||
KEVFFL_DUMP(NOTE_EXTEND);
|
||||
#if HAVE_NOTE_TRUNCATE
|
||||
KEVFFL_DUMP(NOTE_TRUNCATE);
|
||||
#endif
|
||||
KEVFFL_DUMP(NOTE_ATTRIB);
|
||||
KEVFFL_DUMP(NOTE_LINK);
|
||||
KEVFFL_DUMP(NOTE_RENAME);
|
||||
#if HAVE_NOTE_REVOKE
|
||||
KEVFFL_DUMP(NOTE_REVOKE);
|
||||
strcat(buf, ")");
|
||||
#endif
|
||||
buf[strlen(buf) - 1] = ')';
|
||||
|
||||
return (buf);
|
||||
}
|
||||
@ -120,7 +124,7 @@ kevent_flags_dump(struct kevent *kev)
|
||||
#if HAVE_EV_RECEIPT
|
||||
KEVFL_DUMP(EV_RECEIPT);
|
||||
#endif
|
||||
strcat(buf, ")");
|
||||
buf[strlen(buf) - 1] = ')';
|
||||
|
||||
return (buf);
|
||||
}
|
||||
@ -135,7 +139,7 @@ kevent_to_str(struct kevent *kev)
|
||||
kevent_flags_dump(kev),
|
||||
kevent_fflags_dump(kev),
|
||||
(u_int) kev->ident,
|
||||
kev->data,
|
||||
(int) kev->data,
|
||||
kev->udata);
|
||||
return (strdup(buf));
|
||||
}
|
||||
@ -216,8 +220,10 @@ main(int argc, char **argv)
|
||||
test_evfilt_signal();
|
||||
if (test_vnode)
|
||||
test_evfilt_vnode();
|
||||
#if FIXME
|
||||
if (test_timer)
|
||||
test_evfilt_timer();
|
||||
#endif
|
||||
|
||||
puts("all tests completed.");
|
||||
return (0);
|
||||
|
76
test/read.c
76
test/read.c
@ -58,22 +58,25 @@ test_kevent_socket_get(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ) wait";
|
||||
struct kevent kev;
|
||||
int nfds;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
kevent_socket_fill();
|
||||
|
||||
nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
|
||||
if (nfds < 1)
|
||||
err(1, "%s: nfds=%d", test_id, nfds);
|
||||
KEV_CMP(kev, sockfd[0], EVFILT_READ, EV_ADD);
|
||||
if ((int)kev.data != 1)
|
||||
err(1, "incorrect data value %d", (int) kev.data); // FIXME: make part of KEV_CMP
|
||||
kev.data = 1;
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
kevent_socket_drain();
|
||||
test_no_kevents();
|
||||
|
||||
kev.flags = EV_DELETE;
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
success(test_id);
|
||||
}
|
||||
|
||||
@ -81,8 +84,7 @@ void
|
||||
test_kevent_socket_clear(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)";
|
||||
struct kevent kev, ret;
|
||||
int nfds;
|
||||
struct kevent kev;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
@ -95,11 +97,8 @@ test_kevent_socket_clear(void)
|
||||
kevent_socket_fill();
|
||||
kevent_socket_fill();
|
||||
|
||||
nfds = kevent(kqfd, NULL, 0, &ret, 1, NULL);
|
||||
if (nfds < 1)
|
||||
err(1, "%s", test_id);
|
||||
kev.data = 2;
|
||||
kevent_cmp(&kev,&ret);
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
/* We filled twice, but drain once. Edge-triggered would not generate
|
||||
additional events.
|
||||
@ -116,46 +115,38 @@ test_kevent_socket_clear(void)
|
||||
}
|
||||
|
||||
void
|
||||
test_kevent_socket_disable(void)
|
||||
test_kevent_socket_disable_and_enable(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)";
|
||||
struct kevent kev;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
/* Add an event, then disable it. */
|
||||
EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DISABLE, 0, 0, &sockfd[0]);
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
kevent_socket_fill();
|
||||
test_no_kevents();
|
||||
kevent_socket_drain();
|
||||
|
||||
success(test_id);
|
||||
}
|
||||
|
||||
void
|
||||
test_kevent_socket_enable(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ, EV_ENABLE)";
|
||||
struct kevent kev, ret;
|
||||
int nfds;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ENABLE, 0, 0, &sockfd[0]);
|
||||
/* Re-enable the knote, then see if an event is generated */
|
||||
kev.flags = EV_ENABLE;
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
kevent_socket_fill();
|
||||
nfds = kevent(kqfd, NULL, 0, &ret, 1, NULL);
|
||||
if (nfds < 1)
|
||||
err(1, "%s", test_id);
|
||||
kev.flags = EV_ADD;
|
||||
kev.data = 1;
|
||||
kevent_cmp(&kev, &ret);
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
kevent_socket_drain();
|
||||
|
||||
kev.flags = EV_DELETE;
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
success(test_id);
|
||||
}
|
||||
|
||||
@ -182,7 +173,7 @@ void
|
||||
test_kevent_socket_oneshot(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)";
|
||||
struct kevent kev, ret;
|
||||
struct kevent kev;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
@ -195,10 +186,8 @@ test_kevent_socket_oneshot(void)
|
||||
|
||||
puts("-- getting one event");
|
||||
kevent_socket_fill();
|
||||
if (kevent(kqfd, NULL, 0, &ret, 1, NULL) != 1)
|
||||
err(1, "%s", test_id);
|
||||
kev.data = 1;
|
||||
kevent_cmp(&kev, &ret);
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
puts("-- checking knote disabled");
|
||||
test_no_kevents();
|
||||
@ -289,7 +278,7 @@ void
|
||||
test_kevent_socket_eof(void)
|
||||
{
|
||||
const char *test_id = "kevent(EVFILT_READ, EV_EOF)";
|
||||
struct kevent kev, ret;
|
||||
struct kevent kev;
|
||||
|
||||
test_begin(test_id);
|
||||
|
||||
@ -302,10 +291,8 @@ test_kevent_socket_eof(void)
|
||||
if (close(sockfd[1]) < 0)
|
||||
err(1, "close(2)");
|
||||
|
||||
if (kevent(kqfd, NULL, 0, &ret, 1, NULL) < 1)
|
||||
err(1, "%s", test_id);
|
||||
kev.flags |= EV_EOF;
|
||||
kevent_cmp(&kev, &ret);
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
/* Delete the watch */
|
||||
EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
|
||||
@ -324,10 +311,9 @@ test_evfilt_read()
|
||||
|
||||
kqfd = kqueue();
|
||||
test_kevent_socket_add();
|
||||
test_kevent_socket_get();
|
||||
test_kevent_socket_disable();
|
||||
test_kevent_socket_enable();
|
||||
test_kevent_socket_del();
|
||||
test_kevent_socket_get();
|
||||
test_kevent_socket_disable_and_enable();
|
||||
test_kevent_socket_oneshot();
|
||||
test_kevent_socket_clear();
|
||||
test_kevent_socket_dispatch();
|
||||
|
@ -109,7 +109,11 @@ test_kevent_signal_enable(void)
|
||||
err(1, "kill");
|
||||
|
||||
kev.flags = EV_ADD | EV_CLEAR;
|
||||
#if LIBKQUEUE
|
||||
kev.data = 1; /* WORKAROUND */
|
||||
#else
|
||||
kev.data = 2; // one extra time from test_kevent_signal_disable()
|
||||
#endif
|
||||
kevent_cmp(&kev, kevent_get(kqfd));
|
||||
|
||||
/* Delete the watch */
|
||||
|
11
test/vnode.c
11
test/vnode.c
@ -55,17 +55,6 @@ test_kevent_vnode_note_delete(void)
|
||||
if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
|
||||
err(1, "%s", test_id);
|
||||
|
||||
/* FIXME: workaround for linux behavior. if the file is open,
|
||||
the delete event isn't registered; an IN_ATTRIB event is fired
|
||||
instead.
|
||||
|
||||
Unfortunately, closing the descriptor causes BSD kqueue to
|
||||
remove the knote, thus the event is never triggered.
|
||||
*/
|
||||
#if LIBKQUEUE
|
||||
close(vnode_fd);
|
||||
#endif
|
||||
|
||||
if (unlink("/tmp/kqueue-test.tmp") < 0)
|
||||
err(1, "unlink");
|
||||
|
||||
|
@ -23,8 +23,15 @@ To checkout the SVN repository, run the following command:
|
||||
<p>
|
||||
<code>svn checkout svn://mark.heily.com/libkqueue</code>
|
||||
|
||||
<h2>Mailing Lists</h2>
|
||||
|
||||
There are two mailing lists: one for
|
||||
<a href="http://groups.google.com/group/libkqueue">general discussion</a>, and one for
|
||||
<a href="http://groups.google.com/group/libkqueue-announce">announcements only</a>.
|
||||
|
||||
<h2>Status</h2>
|
||||
The current implementation status is <a href="status.html">here</a>.
|
||||
|
||||
Most of the API is implemented, with the notable exception of EVFILT_TIMER and EVFILT_USER. More details about the current implementation status is <a href="status.html">here</a>.
|
||||
<p>
|
||||
There are several compatibility issues to be aware of when using this library under Linux:<p>
|
||||
<ol>
|
||||
@ -43,14 +50,8 @@ a <code>revoke(2)</code> system call.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The NOTE_EXTEND flag for the EVFILT_VNODE filter is not supported. An alternative approach is to use a combination of <code>stat(2)</code> and NOTE_ATTRIB to keep track of changes to the file's <code>st_size</code> field.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The NOTE_LINK flag for the EVFILT_VNODE filter is not supported. An alternative approach is to use a combination of <code>stat(2)</code> and NOTE_ATTRIB to keep track of changes to the file's <code>st_nlink</code> field.
|
||||
</li>
|
||||
|
||||
<li>The NOTE_DELETE flag is supported; however, the event will not be triggered if the program holds an open file descriptor to the file being monitored. This behavior isn't documented in any Linux manpage; see <a href="http://lists.schmorp.de/pipermail/libev/2008q4/000443.html">here</a> for discussion. A workaround would be to close the file descriptor after setting the NOTE_DELETE watch.
|
||||
When an EVFILT_SIGNAL event is generated, the <code>data</code> field
|
||||
is set to 1 regardless of how many times the signal was received by the process.
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
|
Loading…
x
Reference in New Issue
Block a user