mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-11-23 03:39:51 +00:00
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:
parent
282f6b9eee
commit
4795cd4e7a
@ -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
|
||||
|
201
kern/kqueue.c
201
kern/kqueue.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */ \
|
||||
}
|
||||
|
10
kern/test.c
10
kern/test.c
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user