diff -ruN --exclude-from=_diff_exclude_from_file linux-2.4.3/arch/i386/config.in linux-2.4.3+fd_events/arch/i386/config.in
--- linux-2.4.3/arch/i386/config.in	Mon Jan  8 16:27:56 2001
+++ linux-2.4.3+fd_events/arch/i386/config.in	Sun Apr  1 16:07:30 2001
@@ -227,6 +227,10 @@
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool 'File Descriptor Events Interface (EXPERIMENTAL)' CONFIG_FILE_EVENTS
+fi
+
 bool 'Power Management support' CONFIG_PM
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -ruN --exclude-from=_diff_exclude_from_file linux-2.4.3/fs/select.c linux-2.4.3+fd_events/fs/select.c
--- linux-2.4.3/fs/select.c	Fri Feb  9 14:29:44 2001
+++ linux-2.4.3+fd_events/fs/select.c	Sun Apr  1 18:42:40 2001
@@ -491,3 +491,91 @@
 	poll_freewait(&table);
 	return err;
 }
+
+#ifdef CONFIG_FILE_EVENTS
+/* Takes an event and registers current->files->fd[fd] to watch for 
+ * ev->mask on ev->fd; when something happens the event structure gets
+ * queued on current->files->file_event_head; this queue is returned
+ * to the user when sys_get_events is called
+ */
+asmlinkage long sys_bind_event(struct fdevent *uev)
+{
+	struct fdevent *ev;
+	int err=0;
+	
+	if( (ev = kmalloc(sizeof(struct fdevent))) ) {
+		err = -ENOMEM;
+		goto out;
+	}
+	
+	if( copy_from_user(ev, uev, sizeof(struct fdevent)) ) {
+		err = -EFAULT;
+		goto out_ev;
+	}
+	
+	switch( ev->fd ) {
+		int i;
+		struct file *file;
+		
+	case FDEVENT_FD_EXISTING:
+		/* set the ev->mask on each existing current->files->fd[*] */
+		for(i=0;i<current->files->max_fds;i++) {
+			file = fget(i);
+			if( file ) {
+				file->f_event_mask = ev->mask;
+				fput(file);
+			}
+		}
+		break;
+		
+	case FDEVENT_FD_DEFAULT:
+		/* set the default mask for new fd to ev->mask */
+		current->file_event_default_mask = ev->mask;
+		break;
+		
+	default:
+		/* set the ev->mask on the specified ev->fd */
+		file = fget(i);
+		if (!file) {
+			err = -EBADF;
+			goto out_ev;
+		}
+		file->f_event_mask = ev->mask;
+		fput(file);
+	}
+
+out_ev:
+	kfree(ev);
+out:
+	return err;
+}
+
+/* see sys_bind_event */
+asmlinkage long sys_get_events(struct fdevent *uevs, unsigned int nevs, long timeout)
+{
+	int ret=0;
+	register file_event_t *ev;
+	register fdevent *uev = uevs;
+	file_event_list_t *list = &current->files->file_event_list;
+	
+	spinlock_bh(list->lock);
+	
+	ev = list->head;
+	while( ev ) {
+		if( copy_to_user( uev, ev->event, sizeof(fdevent) ) ) {
+			if( !ret ) 
+				ret = -EFAULT;
+			break;
+		}
+		ev++;
+		uev++;
+		ret++;
+		if( ret==nevs ) 
+			break;
+	}
+	
+	spinlock_bh(list->lock);
+
+	return ret;
+}
+#endif
diff -ruN --exclude-from=_diff_exclude_from_file linux-2.4.3/include/asm-i386/fdevent.h linux-2.4.3+fd_events/include/asm-i386/fdevent.h
--- linux-2.4.3/include/asm-i386/fdevent.h	Wed Dec 31 19:00:00 1969
+++ linux-2.4.3+fd_events/include/asm-i386/fdevent.h	Sun Apr  1 18:34:33 2001
@@ -0,0 +1,36 @@
+#ifndef __i386_FDEVENT_H
+#define __i386_FDEVENT_H
+
+/* Event types are borowed from poll.h */
+#define FDEVENT_IN	0x0001
+#define FDEVENT_PRI	0x0002
+#define FDEVENT_OUT	0x0004
+#define FDEVENT_ERR	0x0008
+#define FDEVENT_HUP	0x0010
+#define FDEVENT_NVAL	0x0020
+
+/* non standard, sais poll.h */
+#define FDEVENT_RDNORM	0x0040
+#define FDEVENT_RDBAND	0x0080
+#define FDEVENT_WRNORM	0x0100
+#define FDEVENT_WRBAND	0x0200
+#define FDEVENT_MSG	0x0400
+
+struct fdevent;
+
+typedef void (fdevent_fn)(struct fdevent*);
+
+struct fdevent {
+	int fd;
+	unsigned long mask;
+	void *data;
+	fdevent_fn fn;
+};
+
+#define FDEVENT_INIT { 0, 0, NULL, NULL }
+
+/* wildcards for fdevent.fd */
+#define FDEVENT_FD_EXISTING -1
+#define FDEVENT_FD_DEFAULT  -2
+
+#endif
diff -ruN --exclude-from=_diff_exclude_from_file linux-2.4.3/include/linux/fs.h linux-2.4.3+fd_events/include/linux/fs.h
--- linux-2.4.3/include/linux/fs.h	Mon Mar 26 18:48:11 2001
+++ linux-2.4.3+fd_events/include/linux/fs.h	Sun Apr  1 18:34:36 2001
@@ -471,6 +471,25 @@
 	} u;
 };
 
+#ifdef CONFIG_FILE_EVENTS
+
+typedef struct file_event_s {
+	struct file_event_s *next, *prev; /* queue stored in files_struct */
+	struct fdevent event;
+	
+} file_event_t;
+
+typedef struct file_event_list_s {
+	struct file_event_s *head, *tail; /* just like next/prev above */
+	spinlock_t lock;
+} file_event_list_t;
+
+#define FILE_EVENT_INIT { NULL, NULL, FDEVENT_INIT }
+#define FILE_EVENT_LIST_INIT { NULL, NULL, SPIN_LOCK_UNLOCKED }
+
+#endif
+
+
 struct fown_struct {
 	int pid;		/* pid or -pgrp where SIGIO should be sent */
 	uid_t uid, euid;	/* uid/euid of process setting the owner */
@@ -495,6 +514,10 @@
 
 	/* needed for tty driver, and maybe others */
 	void			*private_data;
+#ifdef CONFIG_FILE_EVENTS
+	file_event_t		f_event;
+	unsigned long           f_event_mask;
+#endif
 };
 extern spinlock_t files_lock;
 #define file_list_lock() spin_lock(&files_lock);
diff -ruN --exclude-from=_diff_exclude_from_file linux-2.4.3/include/linux/sched.h linux-2.4.3+fd_events/include/linux/sched.h
--- linux-2.4.3/include/linux/sched.h	Mon Mar 26 18:48:11 2001
+++ linux-2.4.3+fd_events/include/linux/sched.h	Sun Apr  1 18:33:00 2001
@@ -177,6 +177,11 @@
 	fd_set close_on_exec_init;
 	fd_set open_fds_init;
 	struct file * fd_array[NR_OPEN_DEFAULT];
+#ifdef CONFIG_FILE_EVENTS
+	unsigned long file_event_mask;
+	unsigned long file_event_default_mask;
+	file_event_list_t *file_event_list;
+#endif
 };
 
 #define INIT_FILES \
Binary files linux-2.4.3/vmlinux and linux-2.4.3+fd_events/vmlinux differ

