remove unimplemented solaris stuff

git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@328 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2010-09-14 03:05:35 +00:00
parent 70d5840c94
commit bf08b3f898
7 changed files with 13 additions and 622 deletions

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 2009 Mark Heily <mark@heily.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <string.h>
#include "sys/event.h"
#include "private.h"
#define PORTEV_DUMP(pe) dbg_printf("port_event: events=%d source=%hu", \
(pe)->portev_events, (pe)->portev_source)
int
kqueue_init_hook(void)
{
return (0);
}
int
kqueue_hook(struct kqueue *kq)
{
if ((kq->kq_port = port_create()) < 0) {
dbg_perror("port_create(2)");
return (-1);
}
return (0);
}
int
kevent_wait(struct kqueue *kq, const struct timespec *timeout)
{
port_event_t pe[1];
int rv, nget;
dbg_printf("port_get: %d %lu %lu",
kq->kq_port, timeout->tv_sec, timeout->tv_nsec);
nget = 1;
rv = port_getn(kq->kq_port, pe, 1, &nget, (struct timespec *) timeout);
if (rv < 0) {
if (errno == EINTR) {
dbg_puts("signal caught");
return (-1);
}
dbg_perror("port_getn(2)");
return (-1);
}
if (nget > 0) {
dbg_printf(" -- event(s) pending: nget = %d", nget);
PORTEV_DUMP(&pe[0]);
} else {
dbg_puts(" -- no events --");
}
return (nget);
}
int
kevent_copyout(struct kqueue *kq, int nready,
struct kevent *eventlist, int nevents)
{
return (-1);
#if TODO
struct filter *filt;
int i, rv, nret;
if (FD_ISSET(filt->kf_pfd, &kq->kq_rfds)) {
dbg_printf("event(s) for filter #%d", i);
filter_lock(filt);
rv = filt->kf_copyout(filt, eventlist, nevents);
if (rv < 0) {
filter_unlock(filt);
dbg_puts("kevent_copyout failed");
return (-1);
}
nret += rv;
eventlist += rv;
nevents -= rv;
nready--;
filter_unlock(filt);
}
return (nret);
#endif
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2009 Mark Heily <mark@heily.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include "sys/event.h"
#include "private.h"
const struct filter evfilt_proc = {
0, //XXX-FIXME broken: EVFILT_PROC,
};

View File

@ -1,198 +0,0 @@
/*
* Copyright (c) 2009 Mark Heily <mark@heily.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include "sys/event.h"
#include "private.h"
/* Highest signal number supported. POSIX standard signals are < 32 */
#define SIGNAL_MAX 32
struct sentry {
size_t s_cnt;
struct filter *s_filt;
struct knote *s_knote;
};
static pthread_mutex_t sigtbl_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct sentry sigtbl[SIGNAL_MAX];
static void
signal_handler(int sig)
{
struct sentry *s = &sigtbl[sig];
ssize_t n;
dbg_printf("caught sig=%d", sig);
atomic_inc(&s->s_cnt);
n = write(s->s_filt->kf_wfd, &sig, sizeof(sig));//FIXME:errhandling
}
static int
catch_signal(struct filter *filt, struct knote *kn)
{
int sig;
struct sigaction sa;
sig = kn->kev.ident;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = signal_handler;
sa.sa_flags |= SA_RESTART;
sigfillset(&sa.sa_mask);
if (sigaction(kn->kev.ident, &sa, NULL) == -1) {
dbg_perror("sigaction");
return (-1);
}
/* FIXME: will clobber previous entry, if any */
pthread_mutex_lock(&sigtbl_mtx);
sigtbl[kn->kev.ident].s_filt = filt;
sigtbl[kn->kev.ident].s_knote = kn;
pthread_mutex_unlock(&sigtbl_mtx);
dbg_printf("installed handler for signal %d", sig);
return (0);
}
static int
ignore_signal(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, NULL) == -1) {
dbg_perror("sigaction");
return (-1);
}
pthread_mutex_lock(&sigtbl_mtx);
sigtbl[sig].s_filt = NULL;
sigtbl[sig].s_knote = NULL;
pthread_mutex_unlock(&sigtbl_mtx);
dbg_printf("removed handler for signal %d", sig);
return (0);
}
int
evfilt_signal_init(struct filter *filt)
{
return filter_socketpair(filt);
}
void
evfilt_signal_destroy(struct filter *filt)
{
close(filt->kf_pfd);
}
int
evfilt_signal_knote_create(struct filter *filt, struct knote *kn)
{
if (kn->kev.ident >= SIGNAL_MAX) {
dbg_printf("unsupported signal number %u", (u_int) kn->kev.ident);
return (-1);
}
kn->kev.flags |= EV_CLEAR;
return catch_signal(filt, kn);
}
int
evfilt_signal_knote_modify(struct filter *filt, struct knote *kn,
const struct kevent *kev)
{
kn->kev.flags = kev->flags | EV_CLEAR;
return (0);
}
int
evfilt_signal_knote_delete(struct filter *filt, struct knote *kn)
{
return ignore_signal(kn->kev.ident);
}
int
evfilt_signal_knote_enable(struct filter *filt, struct knote *kn)
{
return catch_signal(filt, kn);
}
int
evfilt_signal_knote_disable(struct filter *filt, struct knote *kn)
{
return ignore_signal(kn->kev.ident);
}
int
evfilt_signal_copyout(struct filter *filt,
struct kevent *dst,
int nevents)
{
struct sentry *s;
struct knote *kn;
int sig;
ssize_t n;
n = read(filt->kf_pfd, &sig, sizeof(sig));//FIXME:errhandling
dbg_printf("got sig=%d", sig);
s = &sigtbl[sig];
kn = s->s_knote;
//TODO: READ counter: s->s_knote->kev.data = ?;
/* TODO: dst->data should be the number of times the signal occurred */
dst->ident = sig;
dst->filter = EVFILT_SIGNAL;
dst->udata = kn->kev.udata;
dst->flags = kn->kev.flags;
dst->fflags = 0;
dst->data = 1;
if (kn->kev.flags & EV_DISPATCH) {
ignore_signal(kn->kev.ident);
KNOTE_DISABLE(kn);
} else if (kn->kev.flags & EV_ONESHOT) {
ignore_signal(kn->kev.ident);
knote_free(filt, kn);
}
return (1);
}
const struct filter evfilt_signal = {
EVFILT_SIGNAL,
evfilt_signal_init,
evfilt_signal_destroy,
evfilt_signal_copyout,
evfilt_signal_knote_create,
evfilt_signal_knote_modify,
evfilt_signal_knote_delete,
evfilt_signal_knote_enable,
evfilt_signal_knote_disable,
};

View File

@ -79,49 +79,6 @@ evfilt_socket_destroy(struct filter *filt)
;
}
#if DEADWOOD
// split into multiple funcs
int
evfilt_socket_copyin(struct filter *filt,
struct knote *dst, const struct kevent *src)
{
int port, events;
int rv;
port = filt->kf_kqueue->kq_port;
/* Not supported or not implemented */
if (src->flags & EV_CLEAR) {
dbg_puts("attempt to use unsupported mechanism");
return (-1);
}
if (src->filter == EVFILT_READ)
events = POLLIN;
else
events = POLLOUT;
if (src->flags & EV_DELETE || src->flags & EV_DISABLE) {
rv = port_dissociate(port, PORT_SOURCE_FD, src->ident);
if (rv < 0) {
dbg_perror("port_dissociate(2)");
return (-1);
}
}
if (src->flags & EV_ENABLE || src->flags & EV_ADD) {
rv = port_associate(port, PORT_SOURCE_FD,
src->ident, events, src->udata);
if (rv < 0) {
dbg_perror("port_associate(2)");
return (-1);
}
}
/* XXX-TODO support modifying an existing watch */
return (0);
}
#endif
int
evfilt_socket_knote_create(struct filter *filt, struct knote *kn)
{
@ -195,6 +152,7 @@ evfilt_socket_copyout(struct filter *filt,
dst->data = 0;
}
#else
/* Workaround */
dst->data = 1;
#endif
}

View File

@ -166,7 +166,7 @@ int
evfilt_timer_knote_modify(struct filter *filt, struct knote *kn,
const struct kevent *kev)
{
return (0); /* STUB */
return (-1); /* STUB */
}
int

View File

@ -1,247 +0,0 @@
/*
* Copyright (c) 2009 Mark Heily <mark@heily.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "sys/event.h"
#include "private.h"
int
evfilt_vnode_init(struct filter *filt)
{
return (-1);
}
void
evfilt_vnode_destroy(struct filter *filt)
{
;
}
int
evfilt_vnode_copyin(struct filter *filt,
struct knote *dst, const struct kevent *src)
{
#if TODO
char path[PATH_MAX];
struct stat sb;
uint32_t mask;
if (src->flags & EV_DELETE || src->flags & EV_DISABLE)
return delete_watch(filt->kf_pfd, dst);
if (src->flags & EV_ADD && KNOTE_EMPTY(dst)) {
memcpy(&dst->kev, src, sizeof(*src));
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;
}
if (src->flags & EV_ADD || src->flags & EV_ENABLE) {
/* Convert the fd to a pathname */
if (fd_to_path(&path[0], sizeof(path), src->ident) < 0)
return (-1);
/* Convert the fflags to the inotify mask */
mask = 0;
if (dst->kev.fflags & NOTE_DELETE)
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, %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));
return (-1);
}
}
return (0);
#endif
return (-1);
}
int
evfilt_vnode_copyout(struct filter *filt,
struct kevent *dst,
int nevents)
{
#if TODO
struct inotify_event evt;
struct stat sb;
struct knote *kn;
if (get_one_event(&evt, filt->kf_pfd) < 0)
return (-1);
inotify_event_dump(&evt);
if (evt.mask & IN_IGNORED) {
/* TODO: possibly return error when fs is unmounted */
return (0);
}
kn = knote_lookup_data(filt, evt.wd);
if (kn == NULL) {
dbg_printf("no match for wd # %d", evt.wd);
return (-1);
}
memcpy(dst, &kn->kev, sizeof(*dst));
dst->data = 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 (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 (kn->kev.flags & EV_ONESHOT)
knote_free(kn);
return (1);
#endif
return (-1);
}
int
evfilt_vnode_knote_create(struct filter *filt, struct knote *kn)
{
#if TODO
struct epoll_event ev;
/* Convert the kevent into an epoll_event */
if (kn->kev.filter == EVFILT_READ)
kn->kn_events = EPOLLIN | EPOLLRDHUP;
else
kn->kn_events = EPOLLOUT;
if (kn->kev.flags & EV_ONESHOT || kn->kev.flags & EV_DISPATCH)
kn->kn_events |= EPOLLONESHOT;
if (kn->kev.flags & EV_CLEAR)
kn->kn_events |= EPOLLET;
memset(&ev, 0, sizeof(ev));
ev.events = kn->kn_events;
ev.data.fd = kn->kev.ident;
return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
#endif
return (-1);
}
int
evfilt_vnode_knote_modify(struct filter *filt, struct knote *kn,
const struct kevent *kev)
{
return (-1); /* STUB */
}
int
evfilt_vnode_knote_delete(struct filter *filt, struct knote *kn)
{
#if TODO
if (kn->kev.flags & EV_DISABLE)
return (0);
else
return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
#else
return (-1);
#endif
}
int
evfilt_vnode_knote_enable(struct filter *filt, struct knote *kn)
{
#if TODO
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.events = kn->kn_events;
ev.data.fd = kn->kev.ident;
return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
#else
return (-1);
#endif
}
int
evfilt_vnode_knote_disable(struct filter *filt, struct knote *kn)
{
#if TODO
return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
#else
return (-1);
#endif
}
const struct filter evfilt_vnode = {
0, //EVFILT_VNODE,
evfilt_vnode_init,
evfilt_vnode_destroy,
evfilt_vnode_copyout,
evfilt_vnode_knote_create,
evfilt_vnode_knote_modify,
evfilt_vnode_knote_delete,
evfilt_vnode_knote_enable,
evfilt_vnode_knote_disable,
};

View File

@ -70,6 +70,7 @@ The EVFILT_PROC filter only supports the NOTE_EXIT flag, and the <code>ident</co
</ol>
<h3>Solaris</h3>
Here are the issues to be aware of when using this library under Solaris:<br/>
<ol>
@ -78,6 +79,16 @@ Here are the issues to be aware of when using this library under Solaris:<br/>
Solaris 10 or newer is required. It should work with OpenSolaris and other Solaris-based distributions, but has not been tested.
</li>
<li>
When an EVFILT_READ event is generated, the <code>data</code> field
is set to 1 regardless of how many bytes are available to read.
</li>
<li>
When an EVFILT_TIMER event is generated, the <code>data</code> field
is set to 1 regardless of how many times the timer has been triggered.
</li>
<li>
The EVFILT_VNODE filter is not implemented. This will eventually be implemented
using the PORT_SOURCE_FILE mechanism described <a href="http://blogs.sun.com/praks/entry/file_events_notification">here</a>.