fixup queue.h

git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@218 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2010-02-27 22:05:16 +00:00
parent 282f6b9eee
commit 4795cd4e7a
4 changed files with 191 additions and 37 deletions

View File

@ -17,15 +17,25 @@
obj-m = kqueue.o
KVERSION = $(shell uname -r)
all:
all: kqueue.ko modtest
kqueue.ko: kqueue.c
make -C /lib/modules/`uname -r`/build M=$(PWD) modules
clean:
make -C /lib/modules/`uname -r`/build M=$(PWD) clean
rm -f modtest
update: all
rmmod kqueue
insmod ./kqueue.ko
chmod 777 /dev/kqueue
modtest: test.c
gcc -o modtest -Wall -Werror test.c
edit:
$(EDITOR) Makefile *.[ch]
check: modtest
./modtest

View File

@ -1,17 +1,36 @@
/*
/*-
* Copyright (c) 2010 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.
* Includes portions of /usr/src/sys/kern/kern_event.c which is
*
* 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.
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
* Copyright 2004 John-Mark Gurney <jmg@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Portions based on
$FreeBSD: src/sys/kern/kern_event.c,v 1.126.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $
*/
#include <linux/cdev.h>
@ -25,9 +44,7 @@
#include <linux/uaccess.h>
#include "../include/sys/event.h"
/* Max. number of descriptors that can be associated with a kqueue descriptor */
#define KQUEUE_FD_MAX 10
#include "queue.h"
static int kqueue_open (struct inode *inode, struct file *file);
static int kqueue_release (struct inode *inode, struct file *file);
@ -35,7 +52,7 @@ static int kqueue_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static ssize_t kqueue_read(struct file *file, char __user *buf,
size_t lbuf, loff_t *ppos);
static ssize_t kqueue_write(struct file *file, char __user *buf,
static ssize_t kqueue_write(struct file *file, const char __user *buf,
size_t lbuf, loff_t *ppos);
struct file_operations fops = {
@ -48,8 +65,128 @@ struct file_operations fops = {
};
struct kqueue_data {
int kq_fd[KQUEUE_FD_MAX];
size_t kq_cnt;
spinlock_t kq_lock;
};
/*
* Flags for knote call
*/
#define KNF_LISTLOCKED 0x0001 /* knlist is locked */
#define KNF_NOKQLOCK 0x0002 /* do not keep KQ_LOCK */
#define KNOTE(list, hist, flags) knote(list, hist, flags)
#define KNOTE_LOCKED(list, hint) knote(list, hint, KNF_LISTLOCKED)
#define KNOTE_UNLOCKED(list, hint) knote(list, hint, 0)
#define KNLIST_EMPTY(list) SLIST_EMPTY(&(list)->kl_list)
/************* BEGIN COPY FROM sys/event.h ***************************/
struct knote;
/*
* Flag indicating hint is a signal. Used by EVFILT_SIGNAL, and also
* shared by EVFILT_PROC (all knotes attached to p->p_klist)
*/
#define NOTE_SIGNAL 0x08000000
struct filterops {
int f_isfd; /* true if ident == filedescriptor */
int (*f_attach)(struct knote *kn);
void (*f_detach)(struct knote *kn);
int (*f_event)(struct knote *kn, long hint);
};
/*
* Setting the KN_INFLUX flag enables you to unlock the kq that this knote
* is on, and modify kn_status as if you had the KQ lock.
*
* kn_sfflags, kn_sdata, and kn_kevent are protected by the knlist lock.
*/
struct knote {
SLIST_ENTRY(knote) kn_link; /* for kq */
SLIST_ENTRY(knote) kn_selnext; /* for struct selinfo */
struct knlist *kn_knlist; /* f_attach populated */
TAILQ_ENTRY(knote) kn_tqe;
struct kqueue *kn_kq; /* which queue we are on */
struct kevent kn_kevent;
int kn_status; /* protected by kq lock */
#define KN_ACTIVE 0x01 /* event has been triggered */
#define KN_QUEUED 0x02 /* event is on queue */
#define KN_DISABLED 0x04 /* event is disabled */
#define KN_DETACHED 0x08 /* knote is detached */
#define KN_INFLUX 0x10 /* knote is in flux */
#define KN_MARKER 0x20 /* ignore this knote */
#define KN_KQUEUE 0x40 /* this knote belongs to a kq */
#define KN_HASKQLOCK 0x80 /* for _inevent */
int kn_sfflags; /* saved filter flags */
intptr_t kn_sdata; /* saved data field */
union {
struct file *p_fp; /* file data pointer */
struct proc *p_proc; /* proc pointer */
struct aiocblist *p_aio; /* AIO job pointer */
struct aioliojob *p_lio; /* LIO job pointer */
} kn_ptr;
struct filterops *kn_fop;
void *kn_hook;
#define kn_id kn_kevent.ident
#define kn_filter kn_kevent.filter
#define kn_flags kn_kevent.flags
#define kn_fflags kn_kevent.fflags
#define kn_data kn_kevent.data
#define kn_fp kn_ptr.p_fp
};
static void filt_kqdetach(struct knote *kn);
static int filt_kqueue(struct knote *kn, long hint);
static int filt_procattach(struct knote *kn);
static void filt_procdetach(struct knote *kn);
static int filt_proc(struct knote *kn, long hint);
static int filt_fileattach(struct knote *kn);
static void filt_timerexpire(void *knx);
static int filt_timerattach(struct knote *kn);
static void filt_timerdetach(struct knote *kn);
static int filt_timer(struct knote *kn, long hint);
static struct filterops file_filtops =
{ 1, filt_fileattach, NULL, NULL };
static struct filterops kqread_filtops =
{ 1, NULL, filt_kqdetach, filt_kqueue };
/* XXX - move to kern_proc.c? */
static struct filterops proc_filtops =
{ 0, filt_procattach, filt_procdetach, filt_proc };
static struct filterops timer_filtops =
{ 0, filt_timerattach, filt_timerdetach, filt_timer };
/************* END COPY FROM sys/event.h ***************************/
struct kfilter {
/* filter operations */
int (*kf_init)(struct filter *);
void (*kf_destroy)(struct filter *);
int (*kf_copyout)(struct filter *, struct kevent *, int);
/* knote operations */
int (*kn_create)(struct filter *, struct knote *);
int (*kn_modify)(struct filter *, struct knote *,
const struct kevent *);
int (*kn_delete)(struct filter *, struct knote *);
int (*kn_enable)(struct filter *, struct knote *);
int (*kn_disable)(struct filter *, struct knote *);
#if DEADWOOD
struct eventfd *kf_efd; /* Used by user.c */
int kf_pfd; /* fd to poll(2) for readiness */
int kf_wfd; /* fd to write when an event occurs */
u_int kf_timeres; /* timer resolution, in miliseconds */
sigset_t kf_sigmask;
struct evfilt_data *kf_data; /* filter-specific data */
RB_HEAD(knt, knote) kf_knote;
TAILQ_HEAD(, knote) kf_event; /* events that have occurred */
struct kqueue *kf_kqueue;
#endif
};
static int major;
@ -81,7 +218,7 @@ static int kqueue_open (struct inode *inode, struct file *file)
printk("kqueue: kmalloc failed\n");
return -1;
}
memset(kq, 0, sizeof(*kq));
spin_lock_init(&kq->kq_lock);
file->private_data = kq;
/* FIXME Unresolved symbols
kq->kq_fd[0] = epoll_create1(0);
@ -93,14 +230,7 @@ static int kqueue_open (struct inode *inode, struct file *file)
static int kqueue_release (struct inode *inode, struct file *file)
{
struct kqueue_data *kq = file->private_data;
int i;
printk("kqueue_release\n");
for (i = 0; i < kq->kq_cnt; i++) {
printk(KERN_INFO "also close fd %d...\n", kq->kq_fd[i]);
sys_close(kq->kq_fd[i]);
}
kfree(file->private_data);
return 0;
@ -109,16 +239,11 @@ static int kqueue_release (struct inode *inode, struct file *file)
static int kqueue_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct kqueue_data *kq = file->private_data;
int fd;
if (copy_from_user(&fd, (int *)arg, sizeof(int)))
return -EFAULT;
if (kq->kq_cnt >= KQUEUE_FD_MAX)
return -EMFILE;
kq->kq_fd[kq->kq_cnt++] = fd;
printk(KERN_INFO "added fd %d\n", fd);
return 0;
@ -127,13 +252,27 @@ static int kqueue_ioctl(struct inode *inode, struct file *file,
static ssize_t kqueue_read(struct file *file, char __user *buf,
size_t lbuf, loff_t *ppos)
{
struct kqueue_data *kq = file->private_data;
spin_lock(&kq->kq_lock);
//STUB
spin_unlock(&kq->kq_lock);
return sizeof(struct kevent);
}
static ssize_t kqueue_write(struct file *file, char __user *buf,
static ssize_t kqueue_write(struct file *file, const char __user *buf,
size_t lbuf, loff_t *ppos)
{
struct kqueue_data *kq = file->private_data;
char kbuf[4];
spin_lock(&kq->kq_lock);
copy_from_user(kbuf, buf, 4);
printk("%zu bytes: %s", lbuf, kbuf);
spin_unlock(&kq->kq_lock);
return sizeof(struct kevent);
}

View File

@ -33,8 +33,6 @@
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
#include <sys/cdefs.h>
/*
* This file defines four types of data structures: singly-linked lists,
* singly-linked tail queues, lists and tail queues.
@ -325,8 +323,9 @@ struct { \
/*
* List declarations.
* NOTE: LIST_HEAD conflicts with a Linux macro.
*/
#define LIST_HEAD(name, type) \
#define FIXME_LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}

View File

@ -25,11 +25,15 @@
int
main(int argc, char **argv)
{
int fd, x;
int fd;
fd = open("/dev/kqueue", 0);
fd = open("/dev/kqueue", O_RDWR);
if (fd < 0)
err(1, "open()");
printf("kqfd = %d\n", fd);
#if OLD
int x;
x = 1;
if (ioctl(fd, 1234, (char *) &x) < 0)
@ -37,6 +41,8 @@ main(int argc, char **argv)
x = 2;
if (ioctl(fd, 1234, (char *) &x) < 0)
err(1, "ioctl");
#endif
write(fd, "hi\n", 3);
close(fd);
puts("ok");