diff -ruN linux-2.3.13-pre5-vanilla/arch/alpha/kernel/entry.S linux-2.3.13-pre5-devt/arch/alpha/kernel/entry.S
--- linux-2.3.13-pre5-vanilla/arch/alpha/kernel/entry.S	Thu Aug  5 19:02:51 1999
+++ linux-2.3.13-pre5-devt/arch/alpha/kernel/entry.S	Thu Aug  5 19:05:39 1999
@@ -1147,3 +1147,8 @@
 	.quad sys_capget
 	.quad sys_capset
 	.quad sys_sendfile			/* 370 */
+	.quad sys_timer_create
+	.quad sys_timer_settime
+	.quad sys_timer_gettime
+	.quad sys_timer_getoverrun
+	.quad sys_timer_delete			/* 375 */
diff -ruN linux-2.3.13-pre5-vanilla/arch/arm/kernel/calls.S linux-2.3.13-pre5-devt/arch/arm/kernel/calls.S
--- linux-2.3.13-pre5-vanilla/arch/arm/kernel/calls.S	Sat Jul 24 16:26:05 1999
+++ linux-2.3.13-pre5-devt/arch/arm/kernel/calls.S	Thu Aug  5 19:05:39 1999
@@ -200,8 +200,13 @@
 		.long	SYMBOL_NAME(sys_ni_syscall)
 		.long	SYMBOL_NAME(sys_ni_syscall)
 /* 190 */	.long	SYMBOL_NAME(sys_vfork_wrapper)
+		.long	SYMBOL_NAME(sys_timer_create)
+		.long	SYMBOL_NAME(sys_timer_settime)
+		.long	SYMBOL_NAME(sys_timer_gettime)
+		.long	SYMBOL_NAME(sys_timer_getoverrun)
+/* 195 */	.long	SYMBOL_NAME(sys_timer_delete)
 
-		.rept	NR_syscalls-186
+		.rept	NR_syscalls-195
 			.long	SYMBOL_NAME(sys_ni_syscall)
 		.endr
 #endif
diff -ruN linux-2.3.13-pre5-vanilla/arch/i386/kernel/entry.S linux-2.3.13-pre5-devt/arch/i386/kernel/entry.S
--- linux-2.3.13-pre5-vanilla/arch/i386/kernel/entry.S	Thu Aug  5 19:02:52 1999
+++ linux-2.3.13-pre5-devt/arch/i386/kernel/entry.S	Thu Aug  5 19:05:39 1999
@@ -560,6 +560,11 @@
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_timer_create)
+	.long SYMBOL_NAME(sys_timer_settime)
+	.long SYMBOL_NAME(sys_timer_gettime)
+	.long SYMBOL_NAME(sys_timer_getoverrun)
+	.long SYMBOL_NAME(sys_timer_delete)	/* 195 */
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
@@ -567,6 +572,6 @@
 	 * entries. Don't panic if you notice that this hasn't
 	 * been shrunk every time we add a new system call.
 	 */
-	.rept NR_syscalls-190
+	.rept NR_syscalls-195
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -ruN linux-2.3.13-pre5-vanilla/arch/m68k/kernel/entry.S linux-2.3.13-pre5-devt/arch/m68k/kernel/entry.S
--- linux-2.3.13-pre5-vanilla/arch/m68k/kernel/entry.S	Sun Jun 20 11:40:26 1999
+++ linux-2.3.13-pre5-devt/arch/m68k/kernel/entry.S	Thu Aug  5 19:05:39 1999
@@ -609,6 +609,11 @@
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_timer_create)
+	.long SYMBOL_NAME(sys_timer_settime)
+	.long SYMBOL_NAME(sys_timer_gettime)
+	.long SYMBOL_NAME(sys_timer_getoverrun)
+	.long SYMBOL_NAME(sys_timer_delete)	/* 195 */
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -ruN linux-2.3.13-pre5-vanilla/arch/mips/kernel/irix5sys.h linux-2.3.13-pre5-devt/arch/mips/kernel/irix5sys.h
--- linux-2.3.13-pre5-vanilla/arch/mips/kernel/irix5sys.h	Thu Jul  1 20:36:17 1999
+++ linux-2.3.13-pre5-devt/arch/mips/kernel/irix5sys.h	Thu Aug  5 19:05:40 1999
@@ -235,7 +235,7 @@
 SYS(irix_unimp, 0)			/* 1213  XXX timer_delete()	*/
 SYS(irix_unimp, 0)			/* 1214  XXX timer_settime()	*/
 SYS(irix_unimp, 0)			/* 1215  XXX timer_gettime()	*/
-SYS(irix_unimp, 0)			/* 1216  XXX timer_setoverrun()	*/
+SYS(irix_unimp, 0)			/* 1216  XXX timer_getoverrun()	*/
 SYS(sys_sched_rr_get_interval, 2)	/* 1217  sched_rr_get_interval()V*/
 SYS(sys_sched_yield, 0)			/* 1218  sched_yield()	       V*/
 SYS(sys_sched_getscheduler, 1)		/* 1219  sched_getscheduler()  V*/
diff -ruN linux-2.3.13-pre5-vanilla/arch/mips/kernel/syscalls.h linux-2.3.13-pre5-devt/arch/mips/kernel/syscalls.h
--- linux-2.3.13-pre5-vanilla/arch/mips/kernel/syscalls.h	Thu Jul  1 20:36:18 1999
+++ linux-2.3.13-pre5-devt/arch/mips/kernel/syscalls.h	Thu Aug  5 19:05:40 1999
@@ -225,3 +225,8 @@
 SYS(sys_sendfile, 3)
 SYS(sys_ni_syscall, 0)
 SYS(sys_ni_syscall, 0)
+SYS(sys_timer_create, 3)			/* 4210 */
+SYS(sys_timer_settime, 4)
+SYS(sys_timer_gettime, 2)
+SYS(sys_timer_getoverrun, 1)
+SYS(sys_timer_delete, 1)
diff -ruN linux-2.3.13-pre5-vanilla/arch/ppc/kernel/misc.S linux-2.3.13-pre5-devt/arch/ppc/kernel/misc.S
--- linux-2.3.13-pre5-vanilla/arch/ppc/kernel/misc.S	Thu Jul  1 20:36:20 1999
+++ linux-2.3.13-pre5-devt/arch/ppc/kernel/misc.S	Thu Aug  5 19:05:40 1999
@@ -894,4 +894,9 @@
 	.long sys_ni_syscall		/* streams1 */
 	.long sys_ni_syscall		/* streams2 */
 	.long sys_vfork
-	.space (NR_syscalls-183)*4
+	.long sys_timer_create	/* 190 */
+	.long sys_timer_settime
+	.long sys_timer_gettime
+	.long sys_timer_getoverrun
+	.long sys_timer_delete	/* 194 */
+	.space (NR_syscalls-194)*4
diff -ruN linux-2.3.13-pre5-vanilla/arch/ppc/kernel/smp.c linux-2.3.13-pre5-devt/arch/ppc/kernel/smp.c
--- linux-2.3.13-pre5-vanilla/arch/ppc/kernel/smp.c	Thu Aug  5 19:02:52 1999
+++ linux-2.3.13-pre5-devt/arch/ppc/kernel/smp.c	Thu Aug  5 19:05:40 1999
@@ -39,6 +39,7 @@
 int first_cpu_booted = 0;
 int smp_threads_ready = 0;
 volatile int smp_commenced = 0;
+int cpu_nr = 1;
 int smp_num_cpus = 1;
 struct cpuinfo_PPC cpu_data[NR_CPUS];
 struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
@@ -244,7 +245,7 @@
 	extern struct task_struct *current_set[NR_CPUS];
 	extern void __secondary_start_psurge(void);
 	extern void __secondary_start_chrp(void);
-	int i, cpu_nr;
+	int i;
 	struct task_struct *p;
 	unsigned long a;
 
diff -ruN linux-2.3.13-pre5-vanilla/arch/sparc/kernel/systbls.S linux-2.3.13-pre5-devt/arch/sparc/kernel/systbls.S
--- linux-2.3.13-pre5-vanilla/arch/sparc/kernel/systbls.S	Sun Jun 20 11:39:49 1999
+++ linux-2.3.13-pre5-devt/arch/sparc/kernel/systbls.S	Thu Aug  5 19:05:40 1999
@@ -37,8 +37,8 @@
 /*90*/	.long sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall
 /*95*/	.long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/	.long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
-/*105*/	.long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall
-/*110*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+/*105*/	.long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_timer_create, sys_timer_settime
+/*110*/	.long sys_timer_gettime, sys_timer_getoverrun, sys_timer_delete, sys_nis_syscall, sys_nis_syscall
 /*115*/	.long sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.long sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
 /*125*/	.long sys_nis_syscall, sys_setreuid, sys_setregid, sys_rename, sys_truncate
diff -ruN linux-2.3.13-pre5-vanilla/arch/sparc64/kernel/sys_sparc32.c linux-2.3.13-pre5-devt/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.3.13-pre5-vanilla/arch/sparc64/kernel/sys_sparc32.c	Thu Aug  5 19:02:52 1999
+++ linux-2.3.13-pre5-devt/arch/sparc64/kernel/sys_sparc32.c	Thu Aug  5 19:05:40 1999
@@ -3849,3 +3849,113 @@
 
 	return ret;
 }
+
+struct itimerspec32 {
+	struct  timespec32 it_interval;
+        struct  timespec32 it_value;
+};
+
+int good_timespec(const struct timespec *ts);
+extern struct k_itimer* lock_timer(struct task_struct *tsk, timer_t timer_id);
+static inline void unlock_timer(struct k_itimer *timr)
+{
+	spin_unlock(&timr->it_lock);
+}
+extern void do_timer_gettime(struct k_itimer *timr, struct itimerspec *cur_setting);
+extern void do_timer_settime(struct k_itimer *timr, int flags, struct itimerspec *new_setting, struct itimerspec *old_setting);
+extern int sys_timer_create(clockid_t which_clock, sigevent_t *timer_event_spec, timer_t *created_timer_id);
+
+asmlinkage int sys32_timer_create(clockid_t which_clock, sigevent_t32 *timer_event_spec, timer_t *created_timer_id);
+{
+	mm_segment_t old_fs;
+	sigevent_t tes;
+	int ret, new_timer_id;
+	
+	if (timer_event_spec) {
+		memset (&tes, 0, sizeof(tes));
+		if (get_user (tes.sigev_value.sival_int, &timer_event_spec->sigev_value.sival_int) ||
+		    __get_user (tes.sigev_signo, &timer_event_spec->sigev_signo) ||
+		    __get_user (tes.sigev_notify, &timer_event_spec->sigev_notify) ||
+		    __get_user (tes._sigev_un._sigev_thread._attribute, &timer_event_spec->_sigev_un._sigev_thread._attribute))
+			return -EFAULT;
+		/* As sigev_value is a union of 32bit int and 64bit void *, put the int twice into the ptr, so that when
+		   actually sending the signal both sival_int and sival_ptr will result in correct operation. */
+		tes.sigev_value.sival_ptr = (void *)((long)tes.sigev_value.sival_int<<32 | tes.sigev_value.sival_int);
+		old_fs = get_fs ();
+		set_fs (KERNEL_DS);
+		ret = sys_timer_create (which_clock, &tes, &new_timer_id);
+		set_fs (old_fs);
+		if (!ret) {
+			if (put_user (new_timer_id, created_timer_id))
+				return -EFAULT;
+		}
+		return ret;
+	} else
+		return sys_timer_create (which_clock, NULL, created_timer_id);
+}
+
+asmlinkage int sys32_timer_gettime(timer_t timer_id, struct itimerspec32 *setting)
+{
+	struct k_itimer *timr;
+	struct itimerspec cur_setting;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	do_timer_gettime(timr, &cur_setting);
+
+	unlock_timer(timr);
+	
+	if (put_user (cur_setting.it_interval.tv_sec, &setting->it_interval.tv_sec) ||
+	    __put_user (cur_setting.it_interval.tv_nsec, &setting->it_interval.tv_nsec) ||
+	    __put_user (cur_setting.it_value.tv_sec, &setting->it_value.tv_sec) ||
+	    __put_user (cur_setting.it_value.tv_nsec, &setting->it_value.tv_nsec))
+		return -EFAULT;		    
+
+	return 0;
+}
+
+asmlinkage int sys32_timer_settime(timer_t timer_id, int flags, struct itimerspec32 *new_setting,
+				   struct itimerspec32 *old_setting)
+{
+	struct k_itimer *timr;
+	struct itimerspec new_spec, old_spec;
+	int error = 0;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	if (new_setting == NULL) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	if (get_user (new_spec.it_interval.tv_sec, &new_setting->it_interval.tv_sec) ||
+	    __get_user (new_spec.it_interval.tv_nsec, &new_setting->it_interval.tv_nsec) ||
+	    __get_user (new_spec.it_value.tv_sec, &new_setting->it_value.tv_sec) ||
+	    __get_user (new_spec.it_value.tv_nsec, &new_setting->it_value.tv_nsec)) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	if ((!good_timespec(&new_spec.it_interval)) ||
+	    (!good_timespec(&new_spec.it_value))) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	do_timer_settime(timr, flags, &new_spec,
+			 old_setting ? &old_spec : NULL);
+
+	if (old_setting) {
+		if (put_user (old_spec.it_interval.tv_sec, &old_setting->it_interval.tv_sec) ||
+		    __put_user (old_spec.it_interval.tv_nsec, &old_setting->it_interval.tv_nsec) ||
+		    __put_user (old_spec.it_value.tv_sec, &old_setting->it_value.tv_sec) ||
+		    __put_user (old_spec.it_value.tv_nsec, &old_setting->it_value.tv_nsec))
+			error = -EFAULT;
+	}
+
+out:
+	unlock_timer(timr);
+	return error;
+}
diff -ruN linux-2.3.13-pre5-vanilla/arch/sparc64/kernel/systbls.S linux-2.3.13-pre5-devt/arch/sparc64/kernel/systbls.S
--- linux-2.3.13-pre5-vanilla/arch/sparc64/kernel/systbls.S	Thu Aug  5 19:02:52 1999
+++ linux-2.3.13-pre5-devt/arch/sparc64/kernel/systbls.S	Thu Aug  5 19:05:40 1999
@@ -38,8 +38,8 @@
 /*90*/	.word sys_dup2, sys_nis_syscall, sys32_fcntl, sys32_select, sys_nis_syscall
 	.word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
-	.word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall
-/*110*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+	.word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys32_timer_create, sys32_timer_settime
+/*110*/ .word sys32_timer_gettime, sys_timer_getoverrun, sys_timer_delete, sys_nis_syscall, sys_nis_syscall
 	.word sys_nis_syscall, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.word sys32_readv, sys32_writev, sys32_settimeofday, sys_fchown, sys_fchmod
 	.word sys_nis_syscall, sys32_setreuid, sys32_setregid, sys_rename, sys_truncate
@@ -68,7 +68,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
 /*250*/	.word sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
-	.word sys_aplib
+/*255*/	.word sys_aplib
 
 	/* Now the 64-bit native Linux syscall table. */
 
@@ -97,8 +97,8 @@
 /*90*/	.word sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall
 	.word sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
 /*100*/	.word sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
-	.word sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall
-/*110*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_recvmsg, sys_sendmsg
+	.word sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_timer_create, sys_timer_settime
+/*110*/ .word sys_timer_gettime, sys_timer_getoverrun, sys_timer_delete, sys_recvmsg, sys_sendmsg
 	.word sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_getsockopt, sys_getcwd
 /*120*/	.word sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
 	.word sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
@@ -127,7 +127,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
 /*250*/	.word sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
-	.word sys_aplib
+/*255*/	.word sys_aplib
 
 	/* Now the 32-bit SunOS syscall table. */
 
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-alpha/siginfo.h linux-2.3.13-pre5-devt/include/asm-alpha/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-alpha/siginfo.h	Sun Jun 20 11:39:59 1999
+++ linux-2.3.13-pre5-devt/include/asm-alpha/siginfo.h	Thu Aug  5 19:05:48 1999
@@ -67,6 +67,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-alpha/unistd.h linux-2.3.13-pre5-devt/include/asm-alpha/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-alpha/unistd.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/asm-alpha/unistd.h	Thu Aug  5 19:05:49 1999
@@ -308,6 +308,11 @@
 #define __NR_capget			368
 #define __NR_capset			369
 #define __NR_sendfile			370
+#define __NR_timer_create		371
+#define __NR_timer_settime		372
+#define __NR_timer_gettime		373
+#define __NR_timer_getoverrun		374
+#define __NR_timer_delete		375
 
 #if defined(__LIBRARY__) && defined(__GNUC__)
 
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-arm/siginfo.h linux-2.3.13-pre5-devt/include/asm-arm/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-arm/siginfo.h	Sun Jun 20 11:39:59 1999
+++ linux-2.3.13-pre5-devt/include/asm-arm/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -67,6 +67,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-arm/unistd.h linux-2.3.13-pre5-devt/include/asm-arm/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-arm/unistd.h	Mon Jun 21 22:33:31 1999
+++ linux-2.3.13-pre5-devt/include/asm-arm/unistd.h	Thu Aug  5 19:05:49 1999
@@ -198,6 +198,11 @@
 					/* 188 reserved */
 					/* 189 reserved */
 #define __NR_vfork			(__NR_SYSCALL_BASE+190)
+#define __NR_timer_create		(__NR_SYSCALL_BASE+191)
+#define __NR_timer_settime		(__NR_SYSCALL_BASE+192)
+#define __NR_timer_gettime		(__NR_SYSCALL_BASE+193)
+#define __NR_timer_getoverrun		(__NR_SYSCALL_BASE+194)
+#define __NR_timer_delete		(__NR_SYSCALL_BASE+195)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-i386/siginfo.h linux-2.3.13-pre5-devt/include/asm-i386/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-i386/siginfo.h	Sun Jun 20 11:39:59 1999
+++ linux-2.3.13-pre5-devt/include/asm-i386/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -31,13 +31,14 @@
 		struct {
 			unsigned int _timer1;
 			unsigned int _timer2;
+			sigval_t _sigval2;	/* FIXME: must map to _sigval below because it is the same */
 		} _timer;
 
 		/* POSIX.1b signals */
 		struct {
 			pid_t _pid;		/* sender's pid */
 			uid_t _uid;		/* sender's uid */
-			sigval_t _sigval;
+			sigval_t _sigval;	/* FIXME: move out of union together with _sigval2 */
 		} _rt;
 
 		/* SIGCHLD */
@@ -67,6 +68,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-i386/unistd.h linux-2.3.13-pre5-devt/include/asm-i386/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-i386/unistd.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/asm-i386/unistd.h	Thu Aug  5 19:05:49 1999
@@ -195,6 +195,11 @@
 #define __NR_getpmsg		188	/* some people actually want streams */
 #define __NR_putpmsg		189	/* some people actually want streams */
 #define __NR_vfork		190
+#define __NR_timer_create	191
+#define __NR_timer_settime	192
+#define __NR_timer_gettime	193
+#define __NR_timer_getoverrun	194
+#define __NR_timer_delete	195
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-m68k/siginfo.h linux-2.3.13-pre5-devt/include/asm-m68k/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-m68k/siginfo.h	Wed Aug 19 22:24:44 1998
+++ linux-2.3.13-pre5-devt/include/asm-m68k/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -67,6 +67,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-m68k/unistd.h linux-2.3.13-pre5-devt/include/asm-m68k/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-m68k/unistd.h	Tue Jan 19 19:58:34 1999
+++ linux-2.3.13-pre5-devt/include/asm-m68k/unistd.h	Thu Aug  5 19:05:49 1999
@@ -194,6 +194,11 @@
 #define __NR_getpmsg		188	/* some people actually want streams */
 #define __NR_putpmsg		189	/* some people actually want streams */
 #define __NR_vfork		190
+#define __NR_timer_create	191
+#define __NR_timer_settime	192
+#define __NR_timer_gettime	193
+#define __NR_timer_getoverrun	194
+#define __NR_timer_delete	195
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-mips/siginfo.h linux-2.3.13-pre5-devt/include/asm-mips/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-mips/siginfo.h	Sun Jun 20 11:39:59 1999
+++ linux-2.3.13-pre5-devt/include/asm-mips/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -75,6 +75,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-mips/unistd.h linux-2.3.13-pre5-devt/include/asm-mips/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-mips/unistd.h	Thu Jul  1 20:36:33 1999
+++ linux-2.3.13-pre5-devt/include/asm-mips/unistd.h	Thu Aug  5 19:05:49 1999
@@ -1196,6 +1196,11 @@
 #define __NR_sendfile			(__NR_Linux + 207)
 #define __NR_getpmsg			(__NR_Linux + 208)
 #define __NR_putpmsg			(__NR_Linux + 209)
+#define __NR_timer_create		(__NR_Linux + 210)
+#define __NR_timer_settime		(__NR_Linux + 211)
+#define __NR_timer_gettime		(__NR_Linux + 212)
+#define __NR_timer_getoverrun		(__NR_Linux + 213)
+#define __NR_timer_delete		(__NR_Linux + 214)
 
 /*
  * Offset of the last Linux flavoured syscall
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-ppc/siginfo.h linux-2.3.13-pre5-devt/include/asm-ppc/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-ppc/siginfo.h	Sun Jun 20 11:39:59 1999
+++ linux-2.3.13-pre5-devt/include/asm-ppc/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -67,6 +67,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
@@ -122,7 +124,7 @@
  * SIGSEGV si_codes
  */
 #define SEGV_MAPERR	1	/* address not mapped to object */
-#define SRGV_ACCERR	2	/* invalid permissions for mapped object */
+#define SEGV_ACCERR	2	/* invalid permissions for mapped object */
 #define NSIGSEGV	2
 
 /*
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-ppc/unistd.h linux-2.3.13-pre5-devt/include/asm-ppc/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-ppc/unistd.h	Thu Jul  1 20:36:34 1999
+++ linux-2.3.13-pre5-devt/include/asm-ppc/unistd.h	Thu Aug  5 19:05:49 1999
@@ -194,6 +194,11 @@
 #define __NR_getpmsg		187	/* some people actually want streams */
 #define __NR_putpmsg		188	/* some people actually want streams */
 #define __NR_vfork		189
+#define __NR_timer_create	190
+#define __NR_timer_settime	191
+#define __NR_timer_gettime	192
+#define __NR_timer_getoverrun	193
+#define __NR_timer_delete	194
 
 #define __NR(n)	#n
 
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-sparc/siginfo.h linux-2.3.13-pre5-devt/include/asm-sparc/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-sparc/siginfo.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/asm-sparc/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -70,6 +70,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
@@ -127,7 +129,7 @@
  * SIGSEGV si_codes
  */
 #define SEGV_MAPERR	1	/* address not mapped to object */
-#define SRGV_ACCERR	2	/* invalid permissions for mapped object */
+#define SEGV_ACCERR	2	/* invalid permissions for mapped object */
 #define NSIGSEGV	2
 
 /*
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-sparc/unistd.h linux-2.3.13-pre5-devt/include/asm-sparc/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-sparc/unistd.h	Sun Jun 20 11:40:00 1999
+++ linux-2.3.13-pre5-devt/include/asm-sparc/unistd.h	Thu Aug  5 19:05:49 1999
@@ -123,11 +123,11 @@
 #define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
 #define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
 #define __NR_rt_sigsuspend      107 /* Linux Specific                              */
-/* #define __NR_sigvec          108    SunOS Specific                              */
-/* #define __NR_sigblock        109    SunOS Specific                              */
-/* #define __NR_sigsetmask      110    SunOS Specific                              */
-/* #define __NR_sigpause        111    SunOS Specific                              */
-/* #define __NR_sigstack        112    SunOS Specific                              */
+#define __NR_timer_create	108 /* Linux Specific                              */
+#define __NR_timer_settime	109 /* Linux Specific                              */
+#define __NR_timer_gettime	110 /* Linux Specific                              */
+#define __NR_timer_getoverrun	111 /* Linux Specific                              */
+#define __NR_timer_delete	112 /* Linux Specific                              */
 #define __NR_recvmsg            113 /* Common                                      */
 #define __NR_sendmsg            114 /* Common                                      */
 /* #define __NR_vtrace          115    SunOS Specific                              */
@@ -201,9 +201,9 @@
 #define __NR_sigpending         183 /* Common                                      */
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
-/* #define __NR_pathconf        186    SunOS Specific                              */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
-/* #define __NR_sysconf         188    SunOS Specific                              */
+/* #define __NR_clock_gettime	186    Linux Specific				   */
+/* #define __NR_clock_settime	187    Linux Specific				   */
+/* #define __NR_clock_getres	188    Linux Specific				   */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
 #define __NR_personality        191 /* Linux Specific                              */
@@ -271,6 +271,8 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
+/* Please don't add syscalls above 255.
+   Contact jj@ultra.linux.cz or davem@redhat.com for number assignment.  */
 
 #define _syscall0(type,name) \
 type name(void) \
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-sparc64/siginfo.h linux-2.3.13-pre5-devt/include/asm-sparc64/siginfo.h
--- linux-2.3.13-pre5-vanilla/include/asm-sparc64/siginfo.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/asm-sparc64/siginfo.h	Thu Aug  5 19:05:49 1999
@@ -130,6 +130,8 @@
  */
 #define si_pid		_sifields._kill._pid
 #define si_uid		_sifields._kill._uid
+#define si_timer1	_sifields._timer._timer1
+#define si_timer2	_sifields._timer._timer2
 #define si_status	_sifields._sigchld._status
 #define si_utime	_sifields._sigchld._utime
 #define si_stime	_sifields._sigchld._stime
@@ -187,7 +189,7 @@
  * SIGSEGV si_codes
  */
 #define SEGV_MAPERR	1	/* address not mapped to object */
-#define SRGV_ACCERR	2	/* invalid permissions for mapped object */
+#define SEGV_ACCERR	2	/* invalid permissions for mapped object */
 #define NSIGSEGV	2
 
 /*
@@ -266,7 +268,7 @@
 #ifdef __KERNEL__
 
 typedef struct sigevent32 {
-	sigval_t sigev_value;
+	sigval_t32 sigev_value;
 	int sigev_signo;
 	int sigev_notify;
 	union {
diff -ruN linux-2.3.13-pre5-vanilla/include/asm-sparc64/unistd.h linux-2.3.13-pre5-devt/include/asm-sparc64/unistd.h
--- linux-2.3.13-pre5-vanilla/include/asm-sparc64/unistd.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/asm-sparc64/unistd.h	Thu Aug  5 19:05:49 1999
@@ -123,11 +123,11 @@
 #define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
 #define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
 #define __NR_rt_sigsuspend      107 /* Linux Specific                              */
-/* #define __NR_sigvec          108    SunOS Specific                              */
-/* #define __NR_sigblock        109    SunOS Specific                              */
-/* #define __NR_sigsetmask      110    SunOS Specific                              */
-/* #define __NR_sigpause        111    SunOS Specific                              */
-/* #define __NR_sigstack        112    SunOS Specific                              */
+#define __NR_timer_create	108 /* Linux Specific                              */
+#define __NR_timer_settime	109 /* Linux Specific                              */
+#define __NR_timer_gettime	110 /* Linux Specific                              */
+#define __NR_timer_getoverrun	111 /* Linux Specific                              */
+#define __NR_timer_delete	112 /* Linux Specific                              */
 #define __NR_recvmsg            113 /* Common                                      */
 #define __NR_sendmsg            114 /* Common                                      */
 /* #define __NR_vtrace          115    SunOS Specific                              */
@@ -201,9 +201,9 @@
 #define __NR_sigpending         183 /* Common                                      */
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
-/* #define __NR_pathconf        186    SunOS Specific                              */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
-/* #define __NR_sysconf         188    SunOS Specific                              */
+/* #define __NR_clock_gettime	186    Linux Specific				   */
+/* #define __NR_clock_settime	187    Linux Specific				   */
+/* #define __NR_clock_getres	188    Linux Specific				   */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
 #define __NR_personality        191 /* Linux Specific                              */
@@ -271,6 +271,8 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
+/* Please don't add syscalls above 255.
+   Contact jj@ultra.linux.cz or davem@redhat.com for number assignment.  */
 
 #define _syscall0(type,name) \
 type name(void) \
diff -ruN linux-2.3.13-pre5-vanilla/include/linux/limits.h linux-2.3.13-pre5-devt/include/linux/limits.h
--- linux-2.3.13-pre5-vanilla/include/linux/limits.h	Thu Jul 29 03:21:45 1999
+++ linux-2.3.13-pre5-devt/include/linux/limits.h	Thu Aug  5 19:05:52 1999
@@ -14,6 +14,9 @@
 #define PATH_MAX        4095	/* # chars in a path name */
 #define PIPE_BUF        4096	/* # bytes in atomic write to a pipe */
 
+#define TIMER_MAX         32    /* # POSIX.1b timers a process may have */
+#define DELAYTIMER_MAX INT_MAX	/* # timer expiration overruns a POSIX.1b timer may have */
+
 #define RTSIG_MAX	  32
 
 #endif
diff -ruN linux-2.3.13-pre5-vanilla/include/linux/sched.h linux-2.3.13-pre5-devt/include/linux/sched.h
--- linux-2.3.13-pre5-vanilla/include/linux/sched.h	Thu Aug  5 19:02:55 1999
+++ linux-2.3.13-pre5-devt/include/linux/sched.h	Thu Aug  5 19:15:26 1999
@@ -36,6 +36,7 @@
 #define CLONE_PTRACE	0x00002000	/* set if we want to let tracing continue on the child too */
 #define CLONE_VFORK	0x00004000	/* set if the parent wants the child to wake it up on mm_release */
 #define CLONE_PARENT	0x00008000	/* set if we want to have the same parent as the cloner */
+#define CLONE_ITIMERS   0x00010000      /* set if POSIX.1b itimers are shared */
 
 /*
  * These are the constant used to fake the fixed-point load-average
@@ -240,6 +241,26 @@
  */
 struct user_struct;
 
+/* POSIX.1b interval timer structure. */
+struct k_itimer {
+	spinlock_t it_lock;
+	clockid_t it_clock;		/* which timer type */
+	timer_t it_id;			/* timer id */
+	int it_overrun;			/* number of signals overrun */
+	struct sigevent it_signal;	/* signal to be delivered */
+	struct timespec it_interval;	/* interval (rounded to jiffies) */
+	int it_incr;			/* interval specified in jiffies */
+	struct task_struct *it_process;	/* process to send signal to */
+	struct timer_list it_timer;
+};
+
+/* Structure to maintain the dynamically created POSIX.1b interval timers. */
+struct itimer_struct {
+	atomic_t count;
+	spinlock_t its_lock;
+	struct k_itimer *itimer[TIMER_MAX];	
+};
+
 struct task_struct {
 /* these are hardcoded - don't touch */
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
@@ -295,6 +316,7 @@
 	unsigned long it_real_value, it_prof_value, it_virt_value;
 	unsigned long it_real_incr, it_prof_incr, it_virt_incr;
 	struct timer_list real_timer;
+	struct itimer_struct *posix_timers; /* POSIX.1b Interval Timers */
 	struct tms times;
 	unsigned long start_time;
 	long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
@@ -381,6 +403,7 @@
 /* chld wait */	__WAIT_QUEUE_HEAD_INITIALIZER(name.wait_chldexit), NULL, \
 /* timeout */	SCHED_OTHER,0,0,0,0,0,0,0, \
 /* timer */	{ NULL, NULL, 0, 0, it_real_fn }, \
+/* POSIX.1b timer */ NULL, \
 /* utime */	{0,0,0,0},0, \
 /* per CPU times */ {0, }, {0, }, \
 /* flt */	0,0,0,0,0,0, \
@@ -676,6 +699,7 @@
 extern void exit_fs(struct task_struct *);
 extern void exit_files(struct task_struct *);
 extern void exit_sighand(struct task_struct *);
+extern void exit_itimers(struct task_struct *);
 
 extern int do_execve(char *, char **, char **, struct pt_regs *);
 extern int do_fork(unsigned long, unsigned long, struct pt_regs *);
diff -ruN linux-2.3.13-pre5-vanilla/include/linux/sysctl.h linux-2.3.13-pre5-devt/include/linux/sysctl.h
--- linux-2.3.13-pre5-vanilla/include/linux/sysctl.h	Sat Jul 24 16:26:13 1999
+++ linux-2.3.13-pre5-devt/include/linux/sysctl.h	Thu Aug  5 19:05:52 1999
@@ -93,15 +93,63 @@
 	KERN_SG_BIG_BUFF=29,
 	KERN_ACCT=30,		/* BSD process accounting parameters */
 	KERN_PPC_L2CR=31,	/* l2cr register on PPC */
-
-	KERN_RTSIGNR=32,	/* Number of rt sigs queued */
-	KERN_RTSIGMAX=33,	/* Max queuable */
 	
 	KERN_SHMMAX=34,         /* int: Maximum shared memory segment */
 	KERN_MSGMAX=35,         /* int: Maximum size of a messege */
 	KERN_MSGMNB=36,         /* int: Maximum message queue size */
 	KERN_MSGPOOL=37,        /* int: Maximum system message pool size */
-	KERN_MAX_THREADS=38     /* int: Maximum nr of threads in the system */
+	KERN_MAX_THREADS=38,    /* int: Maximum nr of threads in the system */
+	KERN_ARG_MAX=39,	/* int: Max size of argv[] plus envp[] */
+	KERN_CHILD_MAX=40,	/* int: Max processes allowed to a UID */
+	KERN_CLK_TCK=41,	/* int: Ticks per second (clock_t) */
+	KERN_NGROUPS_MAX=42,	/* int: Max simultaneous groups to which one
+					may belong */
+	KERN_OPEN_MAX=43,	/* int: Max open files per process */
+	KERN_JOB_CONTROL=44,	/* int: Job control supported? */
+	KERN_SAVED_IDS=45,	/* int: Saved IDs (seteuid()) supported? */
+	KERN_PAGE_SIZE=46,	/* int: system memory page size */
+	KERN_NPROCESSORS_CONF=47, /* int: Number of processors configured */
+	KERN_NPROCESSORS_ONLN=48, /* int: Number of processors online */
+	KERN_ASYNCHRONOUS_IO=49, /* int: Supports asynchronous I/O */
+	KERN_FSYNC=50,		/* int: Supports file synchronization */
+	KERN_MAPPED_FILES=51,	/* int: Supports memory mapped files */
+	KERN_MEMLOCK=52,	/* int: Supports process memory locking */
+	KERN_MEMLOCK_RANGE=53,	/* int: Supports memory range locking */
+	KERN_MEMORY_PROTECTION=54, /* int: Supports memory protection */
+	KERN_MESSAGE_PASSING=55, /* int: Supports message passing */
+	KERN_PRIORITIZED_IO=56,	/* int: Supports prioritized I/O */
+	KERN_PRIORITY_SCHEDULING=57, /* int: Supports priority scheduling */
+	KERN_REALTIME_SIGNALS=58, /* int: Supports realtime signals */
+	KERN_SEMAPHORES=59,	/* int: Supports semaphores */
+	KERN_SHARED_MEMORY_OBJECTS=60, /* int: Supports shared memory objects */
+	KERN_SYNCHRONIZED_IO=61, /* int: Supports syncrhonized I/O */
+	KERN_TIMERS=62,		/* int: Supports POSIX timers */
+	KERN_DELAYTIMER_MAX=63,	/* int: Max value of timer overrun */
+	KERN_TIMER_MAX=64,	/* int: Max number of timers per process */
+	KERN_IOV_MAX=65,	/* int: Max number of iovec structures per 
+					readv or writev call */
+	KERN_STREAM_MAX=66,	/* int: Max number of streams one process
+					can have open */
+	KERN_AIO_LISTIO_MAX=67,	/* int: Max number of I/O operations in a
+					single list I/O call */
+	KERN_AIO_MAX=68,	/* int: Max number of outstanding asynchronous
+					I/O operations */
+	KERN_AIO_PRIO_DELTA_MAX=69, /* int: Max amount by which a process can
+					    decrease its asynchronous I/O
+					    priority level from its own
+					    scheduling priority */
+	KERN_MQ_OPEN_MAX=70,	/* int: Max number of open message queues 
+					per process */
+	KERN_MQ_PRIO_MAX=71,	/* int: Max number of message priorities
+					supported by implementation */
+	KERN_SEM_NSEMS_MAX=72,	/* int: Max number of semaphores per process */
+	KERN_SEM_VALUE_MAX=73,	/* int: Max value a semaphore may have */
+	KERN_SIGQUEUE_MAX=74,	/* int: Max number of queued signals that a process may
+				      send and have pending at receiver(s) at a time */
+	KERN_SIGQUEUE_NR=75,	/* int: number of queued signals in the system */
+	KERN_RTSIG_MAX=76,	/* int: Max number of realtime signals reserved for
+					application use */
+	KERN_LINUX_COUNTER_HZ=77 /* int: Frequency of free running counter */
 };
 
 
diff -ruN linux-2.3.13-pre5-vanilla/include/linux/time.h linux-2.3.13-pre5-devt/include/linux/time.h
--- linux-2.3.13-pre5-vanilla/include/linux/time.h	Mon Dec 28 07:18:28 1998
+++ linux-2.3.13-pre5-devt/include/linux/time.h	Thu Aug  5 19:05:52 1999
@@ -26,6 +26,19 @@
  */
 #define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
 
+/* Parameters used to convert the timespec values */
+#ifndef USEC_PER_SEC
+#define USEC_PER_SEC (1000000L)
+#endif
+
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC (1000000000L)
+#endif
+
+#ifndef NSEC_PER_USEC
+#define NSEC_PER_USEC (1000L)
+#endif
+
 static __inline__ unsigned long
 timespec_to_jiffies(struct timespec *value)
 {
@@ -34,15 +47,15 @@
 
 	if (sec >= (MAX_JIFFY_OFFSET / HZ))
 		return MAX_JIFFY_OFFSET;
-	nsec += 1000000000L / HZ - 1;
-	nsec /= 1000000000L / HZ;
+	nsec += NSEC_PER_SEC / HZ - 1;
+	nsec /= NSEC_PER_SEC / HZ;
 	return HZ * sec + nsec;
 }
 
 static __inline__ void
 jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
 {
-	value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
+	value->tv_nsec = (jiffies % HZ) * (NSEC_PER_SEC / HZ);
 	value->tv_sec = jiffies / HZ;
 }
  
@@ -88,5 +101,24 @@
 	struct	timeval it_interval;	/* timer interval */
 	struct	timeval it_value;	/* current value */
 };
+
+
+/* 
+ * Data types for POSIX.1b interval timers.
+ */
+typedef int clockid_t;
+typedef int timer_t;
+
+/*
+ * The IDs of the various system clocks (for POSIX.1b interval timers).
+ */
+#define CLOCK_REALTIME 0
+
+/*
+ * The various flags for setting POSIX.1b interval timers.
+ */
+
+#define TIMER_ABSTIME 0x01
+
 
 #endif
diff -ruN linux-2.3.13-pre5-vanilla/kernel/exit.c linux-2.3.13-pre5-devt/kernel/exit.c
--- linux-2.3.13-pre5-vanilla/kernel/exit.c	Thu Aug  5 19:02:58 1999
+++ linux-2.3.13-pre5-devt/kernel/exit.c	Thu Aug  5 19:05:52 1999
@@ -260,6 +260,34 @@
 	mmdrop(active_mm);
 }
 
+static inline void __exit_itimers(struct task_struct *tsk)
+{
+	struct itimer_struct *timers = tsk->posix_timers;
+	struct k_itimer *timr;
+	int i;
+
+	if (timers == NULL) return;
+	
+	if (atomic_dec_and_test(&timers->count)) {
+		tsk->posix_timers = NULL;
+		for (i = 0; i < TIMER_MAX; i++) {
+			timr = timers->itimer[i];
+			if (timr) {
+				start_bh_atomic();
+				del_timer(&timr->it_timer);
+				end_bh_atomic();
+				kfree(timr);
+			}
+		}
+		kfree(timers);
+	}
+}
+
+void exit_itimers(struct task_struct *tsk)
+{
+	__exit_itimers(tsk);
+}
+
 /*
  * Turn us into a lazy TLB process if we
  * aren't already..
@@ -384,6 +412,7 @@
 	__exit_files(tsk);
 	__exit_fs(tsk);
 	__exit_sighand(tsk);
+	__exit_itimers(tsk);
 	exit_thread();
 	tsk->state = TASK_ZOMBIE;
 	tsk->exit_code = code;
diff -ruN linux-2.3.13-pre5-vanilla/kernel/fork.c linux-2.3.13-pre5-devt/kernel/fork.c
--- linux-2.3.13-pre5-vanilla/kernel/fork.c	Thu Aug  5 19:02:58 1999
+++ linux-2.3.13-pre5-devt/kernel/fork.c	Thu Aug  5 19:05:52 1999
@@ -581,6 +581,23 @@
 	p->flags = new_flags;
 }
 
+
+static inline int copy_itimers(unsigned long clone_flags, struct task_struct * tsk)
+{
+	if (clone_flags & CLONE_ITIMERS) {
+		atomic_inc(&tsk->posix_timers->count);
+		return 0;
+	}
+
+	tsk->posix_timers = kmalloc(sizeof(*tsk->posix_timers), GFP_KERNEL);
+	if (tsk->posix_timers == NULL) return -1;
+	spin_lock_init(&tsk->posix_timers->its_lock);
+	atomic_set(&tsk->posix_timers->count, 1);
+	memset(tsk->posix_timers->itimer, 0, sizeof(tsk->posix_timers->itimer));
+	return 0;
+}
+
+
 /*
  *  Ok, this is the main fork-routine. It copies the system process
  * information (task[nr]) and sets up the necessary registers. It
@@ -680,6 +697,8 @@
 		goto bad_fork_cleanup_files;
 	if (copy_sighand(clone_flags, p))
 		goto bad_fork_cleanup_fs;
+	if (copy_itimers(clone_flags, p))
+		goto bad_fork_cleanup_itimers;
 	if (copy_mm(clone_flags, p))
 		goto bad_fork_cleanup_sighand;
 	retval = copy_thread(0, clone_flags, usp, p, regs);
@@ -724,6 +743,8 @@
 		down(&sem);
 	return retval;
 
+bad_fork_cleanup_itimers:
+	exit_itimers(p);
 bad_fork_cleanup_sighand:
 	exit_sighand(p);
 bad_fork_cleanup_fs:
diff -ruN linux-2.3.13-pre5-vanilla/kernel/itimer.c linux-2.3.13-pre5-devt/kernel/itimer.c
--- linux-2.3.13-pre5-vanilla/kernel/itimer.c	Tue Nov 24 22:51:44 1998
+++ linux-2.3.13-pre5-devt/kernel/itimer.c	Thu Aug  5 19:05:52 1999
@@ -9,14 +9,16 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/malloc.h>
+#include <linux/time.h>
 
 #include <asm/uaccess.h>
 
 /*
- * change timeval to jiffies, trying to avoid the 
+ * change timeval to jiffies, trying to avoid the
  * most obvious overflows..
  *
- * The tv_*sec values are signed, but nothing seems to 
+ * The tv_*sec values are signed, but nothing seems to
  * indicate whether we really should use them as signed values
  * when doing itimers. POSIX doesn't mention this (but if
  * alarm() uses itimers without checking, we have to use unsigned
@@ -168,6 +170,389 @@
 		return error;
 
 	if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
-		return -EFAULT; 
+		return -EFAULT;
+	return 0;
+}
+
+/* PRECONDITION:
+ * timr->it_lock must be locked
+ */
+static void timer_notify_task(struct k_itimer *timr)
+{
+	struct siginfo info;
+	int ret;
+
+	if (timr->it_signal.sigev_notify == SIGEV_SIGNAL) {
+
+		/* Send signal to the process that owns this timer. */
+		info.si_signo = timr->it_signal.sigev_signo;
+		info.si_errno = 0;
+		info.si_code = SI_TIMER;
+		/* TODO: if someone has better ideas what to put in 
+		 * the next two fields...
+		 * si_timer1 is currently used in signal.c to check
+		 * whether a signal from this timer is already in the signal
+		 * queue.
+		 */
+		info.si_timer1 = timr->it_id;
+		info.si_timer2 = 0;
+		info.si_value = timr->it_signal.sigev_value;
+		ret = send_sig_info(info.si_signo, &info, timr->it_process);
+		switch (ret) {
+		case 0:		/* all's well */
+			timr->it_overrun = 0;
+			break;
+		case 1:	/* signal from this timer was already in the queue */
+			timr->it_overrun++;
+			break;
+		default:
+			printk(KERN_WARNING "sending signal failed: %d\n", ret);
+			break;
+		}
+	}
+}
+
+/* This function gets called when a POSIX.1b interval timer expires. */
+static void posix_timer_fn(unsigned long __data)
+{  
+	struct k_itimer *timr = (struct k_itimer *)__data;
+	unsigned long interval;
+
+	spin_lock(&timr->it_lock);
+	
+	timer_notify_task(timr);
+
+	/* Set up the timer for the next interval (if there is one) */
+	if ((interval = timr->it_incr) == 0) goto out;
+		
+	if (interval > (unsigned long) LONG_MAX)
+		interval = LONG_MAX;
+	timr->it_timer.expires = jiffies + interval;
+	add_timer(&timr->it_timer);
+out:
+	spin_unlock(&timr->it_lock);
+}
+
+/* Find the first available slot for the new timer. */
+static int timer_find_slot(struct itimer_struct *timers)
+{
+	int i;
+
+	for (i = 0; i < TIMER_MAX; i++) {
+		if (timers->itimer[i] == NULL) return i;
+	}
+	return -1;
+}
+
+static int good_sigevent(const struct sigevent *sigev)
+{
+	switch (sigev->sigev_notify) {
+	case SIGEV_NONE:
+		break;
+	case SIGEV_SIGNAL:
+		if ((sigev->sigev_signo <= 0) ||
+		    (sigev->sigev_signo > SIGRTMAX))
+			return 0;
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+/* Create a POSIX.1b interval timer. */
+
+asmlinkage int sys_timer_create(clockid_t which_clock,
+				struct sigevent *timer_event_spec,
+				timer_t *created_timer_id)
+{
+	int error = 0;
+	struct k_itimer *new_timer = NULL;
+	struct itimer_struct *timers = current->posix_timers;
+	int new_timer_id;
+ 
+	/* Right now, we only support CLOCK_REALTIME for timers. */
+	if (which_clock != CLOCK_REALTIME) return -EINVAL;
+
+	new_timer = (struct k_itimer *)kmalloc(sizeof(*new_timer), GFP_KERNEL);
+	if (new_timer == NULL) return -EAGAIN;
+
+	spin_lock_init(&new_timer->it_lock);
+	new_timer->it_clock = which_clock;
+	new_timer->it_incr = 0;
+	new_timer->it_overrun = 0;
+
+	if (timer_event_spec) {
+		if (copy_from_user(&new_timer->it_signal, timer_event_spec,
+				   sizeof(new_timer->it_signal))) {
+			error = -EFAULT;
+			goto out;
+		}
+		if (!good_sigevent(&new_timer->it_signal)) {
+			error = -EINVAL;
+			goto out;
+		}
+	}
+	else {
+		new_timer->it_signal.sigev_notify = SIGEV_SIGNAL;
+		new_timer->it_signal.sigev_signo = SIGALRM;
+	}
+
+	new_timer->it_interval.tv_sec = 0;
+	new_timer->it_interval.tv_nsec = 0;
+	new_timer->it_process = current;
+	new_timer->it_timer.next = NULL;
+	new_timer->it_timer.prev = NULL;
+	new_timer->it_timer.expires = 0;
+	new_timer->it_timer.data = (unsigned long)new_timer;
+	new_timer->it_timer.function = posix_timer_fn;
+
+	spin_lock(&timers->its_lock);
+
+	new_timer_id = timer_find_slot(timers);
+	if (new_timer_id == -1) {
+		error = -EAGAIN;
+		goto out;
+	}
+	new_timer->it_id = new_timer_id;
+	timers->itimer[new_timer_id] = new_timer;
+	if (timer_event_spec == NULL) {
+		new_timer->it_signal.sigev_value.sival_int = new_timer_id;
+	}
+
+	if (copy_to_user(created_timer_id, &new_timer_id, sizeof(new_timer_id))) {
+		error = -EFAULT;
+		timers->itimer[new_timer_id] = NULL;
+	}
+
+	spin_unlock(&timers->its_lock);
+out:
+	if (error) {
+		kfree(new_timer);
+	}
+	return error;
+}
+
+
+/* good_timespec
+ *
+ * This function checks the elements of a timespec structure.
+ *
+ * Arguments:
+ * ts       : Pointer to the timespec structure to check
+ *
+ * Return value:
+ * If a NULL pointer was passed in, or the tv_nsec field was less than 0 or
+ * greater than NSEC_PER_SEC, or the tv_sec field was less than 0, this
+ * function returns 0. Otherwise it returns 1.
+ */
+
+int good_timespec(const struct timespec *ts)
+{
+	if (ts == NULL) return 0;
+	if (ts->tv_sec < 0) return 0;
+	if ((ts->tv_nsec < 0) || (ts->tv_nsec >= NSEC_PER_SEC)) return 0;
+	return 1;
+}
+
+inline struct k_itimer* lock_timer(struct task_struct *tsk, timer_t timer_id)
+{
+	struct k_itimer *timr;
+
+	if ((timer_id < 0) || (timer_id >= TIMER_MAX)) return NULL;
+	spin_lock(&tsk->posix_timers->its_lock);
+	timr = tsk->posix_timers->itimer[timer_id];
+	if (timr) spin_lock(&timr->it_lock);
+	spin_unlock(&tsk->posix_timers->its_lock);
+	return timr;
+}
+
+static inline void unlock_timer(struct k_itimer *timr)
+{
+	spin_unlock(&timr->it_lock);
+}
+
+/* Get the time remaining on a POSIX.1b interval timer. */
+void do_timer_gettime(struct k_itimer *timr,
+		      struct itimerspec *cur_setting)
+{
+	unsigned long expires = timr->it_timer.expires;
+
+	if (expires) expires -= jiffies;
+	
+	jiffies_to_timespec(expires, &cur_setting->it_value);
+	cur_setting->it_interval = timr->it_interval;
+}
+
+/* Get the time remaining on a POSIX.1b interval timer. */
+asmlinkage int sys_timer_gettime(timer_t timer_id, struct itimerspec *setting)
+{
+	struct k_itimer *timr;
+	struct itimerspec cur_setting;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	do_timer_gettime(timr, &cur_setting);
+
+	unlock_timer(timr);
+	
+	copy_to_user_ret(setting, &cur_setting, sizeof(cur_setting), -EFAULT);
+
+	return 0;
+}
+
+/* Get the number of overruns of a POSIX.1b interval timer */
+asmlinkage int sys_timer_getoverrun(timer_t timer_id)
+{
+	struct k_itimer *timr;
+	int overrun;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	overrun = timr->it_overrun;
+	
+	unlock_timer(timr);
+
+	return overrun;
+}
+
+static void timer_value_abs_to_rel(struct timespec *val)
+{
+	struct timeval tv;
+	struct timespec ts;
+
+	do_gettimeofday(&tv);
+	ts.tv_sec = tv.tv_sec;
+	ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
+
+	/* check whether the time lies in the past */
+	if ((val->tv_sec < ts.tv_sec) || 
+	    ((val->tv_sec == ts.tv_sec) &&
+	     (val->tv_nsec <= ts.tv_nsec))) {
+		/* expire immediately */
+		val->tv_sec = 0;
+		val->tv_nsec = 0;
+	}
+	else {
+		val->tv_sec -= ts.tv_sec;
+		val->tv_nsec -= ts.tv_nsec;
+		if (val->tv_nsec < 0) {
+			val->tv_nsec += NSEC_PER_SEC;
+			val->tv_sec--;
+		}
+	}
+}
+
+/* Set a POSIX.1b interval timer. */
+void do_timer_settime(struct k_itimer *timr, int flags,
+		      struct itimerspec *new_setting,
+		      struct itimerspec *old_setting)
+{
+	/* disable the timer */
+	start_bh_atomic();
+	del_timer(&timr->it_timer);
+	end_bh_atomic();
+
+	if (old_setting) {
+		do_timer_gettime(timr, old_setting);
+	}
+
+	/* switch off the timer when it_value is zero */
+	if ((new_setting->it_value.tv_sec == 0) &&
+	    (new_setting->it_value.tv_nsec == 0)) {
+		timr->it_incr = 0;
+		timr->it_timer.expires = 0;
+		timr->it_interval.tv_sec = 0;
+		timr->it_interval.tv_nsec = 0;
+		return;
+	}
+
+	timr->it_incr = timespec_to_jiffies(&new_setting->it_interval);
+	/* save the interval rounded to jiffies */
+	jiffies_to_timespec(timr->it_incr, &timr->it_interval);
+
+	if (flags & TIMER_ABSTIME) {
+		timer_value_abs_to_rel(&new_setting->it_value);
+	}
+
+	timr->it_timer.expires = timespec_to_jiffies(&new_setting->it_value) + jiffies;
+
+	/*
+	 * For some reason the timer does not fire immediately if expires is
+	 * equal to jiffies, so the timer callback function is called directly.
+	 */
+	if (timr->it_timer.expires == jiffies) {
+		posix_timer_fn((unsigned long)timr);
+	}
+	else {
+		add_timer(&timr->it_timer);
+	}
+}
+
+
+/* Set a POSIX.1b interval timer */
+asmlinkage int sys_timer_settime(timer_t timer_id, int flags,
+				 const struct itimerspec *new_setting,
+				 struct itimerspec *old_setting)
+{
+	struct k_itimer *timr;
+	struct itimerspec new_spec, old_spec;
+	int error = 0;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	if (new_setting == NULL) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	if (copy_from_user(&new_spec, new_setting, sizeof(new_spec))) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	if ((!good_timespec(&new_spec.it_interval)) ||
+	    (!good_timespec(&new_spec.it_value))) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	do_timer_settime(timr, flags, &new_spec,
+			 old_setting ? &old_spec : NULL);
+
+	if (old_setting) {
+		if (copy_to_user(old_setting, &old_spec, sizeof(old_spec))) {
+			error = -EFAULT;
+		}
+	}
+
+out:
+	unlock_timer(timr);
+	return error;
+}
+
+
+/* Delete a POSIX.1b interval timer. */
+asmlinkage int sys_timer_delete(timer_t timer_id)
+{
+	struct k_itimer *timr;
+
+	timr = lock_timer(current, timer_id);
+	if (!timr) return -EINVAL;
+
+	start_bh_atomic();
+	del_timer(&timr->it_timer);
+	end_bh_atomic();
+
+	spin_lock(&current->posix_timers->its_lock);
+
+	kfree(timr);
+	current->posix_timers->itimer[timer_id] = NULL;
+
+	spin_unlock(&current->posix_timers->its_lock);
+
 	return 0;
 }
diff -ruN linux-2.3.13-pre5-vanilla/kernel/signal.c linux-2.3.13-pre5-devt/kernel/signal.c
--- linux-2.3.13-pre5-vanilla/kernel/signal.c	Sat Jul 10 16:30:50 1999
+++ linux-2.3.13-pre5-devt/kernel/signal.c	Thu Aug  5 19:05:52 1999
@@ -129,64 +129,48 @@
 
 	if (sig) {
 		int reset = 1;
+		struct signal_queue *q, **pp;
 
 		/* Collect the siginfo appropriate to this signal.  */
-		if (sig < SIGRTMIN) {
-			/* XXX: As an extension, support queueing exactly
-			   one non-rt signal if SA_SIGINFO is set, so that
-			   we can get more detailed information about the
-			   cause of the signal.  */
-			/* Deciding not to init these couple of fields is
-			   more expensive that just initializing them.  */
+		pp = &current->sigqueue;
+		q = current->sigqueue;
+
+		/* Find the one we're interested in ... */
+		for ( ; q ; pp = &q->next, q = q->next)
+			if (q->info.si_signo == sig)
+				break;
+		if (q) {
+			if ((*pp = q->next) == NULL)
+				current->sigqueue_tail = pp;
+			*info = q->info;
+			kmem_cache_free(signal_queue_cachep,q);
+			atomic_dec(&nr_queued_signals);
+
+			/* then see if this signal is still pending. */
+			q = *pp;
+			while (q) {
+				if (q->info.si_signo == sig) {
+					reset = 0;
+					break;
+				}
+				q = q->next;
+			}
+		} else {
+			/* Ok, it wasn't in the queue.  It must have
+			   been sent either by a non-rt mechanism and
+			   we ran out of queue space.  So zero out the
+			   info.  */
 			info->si_signo = sig;
 			info->si_errno = 0;
 			info->si_code = 0;
 			info->si_pid = 0;
 			info->si_uid = 0;
-		} else {
-			struct signal_queue *q, **pp;
-			pp = &current->sigqueue;
-			q = current->sigqueue;
-
-			/* Find the one we're interested in ... */
-			for ( ; q ; pp = &q->next, q = q->next)
-				if (q->info.si_signo == sig)
-					break;
-			if (q) {
-				if ((*pp = q->next) == NULL)
-					current->sigqueue_tail = pp;
-				*info = q->info;
-				kmem_cache_free(signal_queue_cachep,q);
-				atomic_dec(&nr_queued_signals);
-				
-				/* then see if this signal is still pending. */
-				q = *pp;
-				while (q) {
-					if (q->info.si_signo == sig) {
-						reset = 0;
-						break;
-					}
-					q = q->next;
-				}
-			} else {
-				/* Ok, it wasn't in the queue.  It must have
-				   been sent either by a non-rt mechanism and
-				   we ran out of queue space.  So zero out the
-				   info.  */
-				info->si_signo = sig;
-				info->si_errno = 0;
-				info->si_code = 0;
-				info->si_pid = 0;
-				info->si_uid = 0;
-			}
 		}
 
 		if (reset)
 			sigdelset(&current->signal, sig);
 		recalc_sigpending(current);
 
-		/* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
-		   we need to xchg out the timer overrun values.  */
 	} else {
 		/* XXX: Once CLONE_PID is in to join those "threads" that are
 		   part of the same "process", look for signals sent to the
@@ -247,11 +231,31 @@
 	return 1;
 }
 
+static void set_siginfo(siginfo_t *info, int sig, int kernel_signal)
+{
+	if (kernel_signal) {
+		info->si_signo = sig;
+		info->si_errno = 0;
+		info->si_code = SI_KERNEL;
+		info->si_pid = 0;
+		info->si_uid = 0;
+	}
+	else {
+		info->si_signo = sig;
+		info->si_errno = 0;
+		info->si_code = SI_USER;
+		info->si_pid = current->pid;
+		info->si_uid = current->uid;
+	}
+}
+
 int
 send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
 {
 	unsigned long flags;
 	int ret;
+	struct signal_queue *q;
+	siginfo_t info_compat;
 
 #if DEBUG_SIG
 printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
@@ -260,9 +264,16 @@
 	ret = -EINVAL;
 	if (sig < 0 || sig > _NSIG)
 		goto out_nolock;
+
+	/* backward compatibility, convert magic info value to real info */
+	if ((info == NULL) || ((unsigned long)info == 1)) {
+		set_siginfo(&info_compat, sig, info != NULL);
+		info = &info_compat;
+	}
+
 	/* The somewhat baroque permissions check... */
 	ret = -EPERM;
-	if ((!info || ((unsigned long)info != 1 && SI_FROMUSER(info)))
+	if (SI_FROMUSER(info)
 	    && ((sig != SIGCONT) || (current->session != t->session))
 	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
@@ -304,63 +315,61 @@
 	if (ignored_signal(sig, t))
 		goto out;
 
-	if (sig < SIGRTMIN) {
-		/* Non-real-time signals are not queued.  */
-		/* XXX: As an extension, support queueing exactly one
-		   non-rt signal if SA_SIGINFO is set, so that we can
-		   get more detailed information about the cause of
-		   the signal.  */
+	/* In case of a POSIX timer generated signal you must check 
+	   if a signal from this timer is already in the queue.
+	   If that is is true, the overrun count will be increased in
+	   itimer.c:posix_timer_fn(). */
+
+	if (info->si_code == SI_TIMER) {
+		for (q = t->sigqueue; q; q = q->next) {
+			if ((q->info.si_code == SI_TIMER) &&
+			    (q->info.si_timer1 == info->si_timer1)) {
+				/* this special value (1) is recognized
+				   only by posix_timer_fn() in itimer.c */
+				ret = 1;
+				goto out;
+			}
+		}
+	}
+	/* If it is not a timer signal, and it is a NON RT signal,
+	   only one signal gets queued, the later ones are discarded.
+	   However, signals coming from posix timers are allowed in order
+	   to be able to maintain the overrun count (see above if stmt.) */
+
+	else if (sig < SIGRTMIN) {
+		/* Non-real-time signals are not queued. */
 		if (sigismember(&t->signal, sig))
 			goto out;
+	}
+
+	/* Real-time signals must be queued if sent by sigqueue, or
+	   some other real-time mechanism.  It is implementation
+	   defined whether kill() does so.  We attempt to do so, on
+	   the principle of least surprise, but since kill is not
+	   allowed to fail with EAGAIN when low on memory we just
+	   make sure at least one signal gets delivered and don't
+	   pass on the info struct.  */
+
+	q = 0;
+	if (atomic_read(&nr_queued_signals) < max_queued_signals) {
+		q = (struct signal_queue *)
+		    kmem_cache_alloc(signal_queue_cachep, GFP_ATOMIC);
+	}
+
+	if (q) {
+		atomic_inc(&nr_queued_signals);
+		q->next = NULL;
+		*t->sigqueue_tail = q;
+		t->sigqueue_tail = &q->next;
+		q->info = *info;
 	} else {
-		/* Real-time signals must be queued if sent by sigqueue, or
-		   some other real-time mechanism.  It is implementation
-		   defined whether kill() does so.  We attempt to do so, on
-		   the principle of least surprise, but since kill is not
-		   allowed to fail with EAGAIN when low on memory we just
-		   make sure at least one signal gets delivered and don't
-		   pass on the info struct.  */
-
-		struct signal_queue *q = 0;
-
-		if (atomic_read(&nr_queued_signals) < max_queued_signals) {
-			q = (struct signal_queue *)
-			    kmem_cache_alloc(signal_queue_cachep, GFP_ATOMIC);
-		}
-		
-		if (q) {
-			atomic_inc(&nr_queued_signals);
-			q->next = NULL;
-			*t->sigqueue_tail = q;
-			t->sigqueue_tail = &q->next;
-			switch ((unsigned long) info) {
-			case 0:
-				q->info.si_signo = sig;
-				q->info.si_errno = 0;
-				q->info.si_code = SI_USER;
-				q->info.si_pid = current->pid;
-				q->info.si_uid = current->uid;
-				break;
-			case 1:
-				q->info.si_signo = sig;
-				q->info.si_errno = 0;
-				q->info.si_code = SI_KERNEL;
-				q->info.si_pid = 0;
-				q->info.si_uid = 0;
-				break;
-			default:
-				q->info = *info;
-				break;
-			}
-		} else {
-			/* If this was sent by a rt mechanism, try again.  */
-			if (info->si_code < 0) {
-				ret = -EAGAIN;
-				goto out;
-			}
-			/* Otherwise, mention that the signal is pending,
-			   but don't queue the info.  */
+		/* If this was sent by a rt mechanism, try again.  */
+		if (info->si_code < 0) {
+			ret = -EAGAIN;
+			goto out;
 		}
+		/* Otherwise, mention that the signal is pending,
+		   but don't queue the info.  */
 	}
 
 	sigaddset(&t->signal, sig);
diff -ruN linux-2.3.13-pre5-vanilla/kernel/sysctl.c linux-2.3.13-pre5-devt/kernel/sysctl.c
--- linux-2.3.13-pre5-vanilla/kernel/sysctl.c	Sat Jul 24 16:26:14 1999
+++ linux-2.3.13-pre5-devt/kernel/sysctl.c	Thu Aug  5 19:05:52 1999
@@ -20,6 +20,13 @@
 #include <linux/utsname.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/limits.h>
+#include <linux/uio.h>
+#include <linux/swap.h>
+#include <linux/mm.h>
+#include <asm/param.h>
+#include <asm/page.h>
+#include <asm/smp.h>
 
 #include <asm/uaccess.h>
 
@@ -37,6 +44,22 @@
 extern int max_threads;
 extern int nr_queued_signals, max_queued_signals;
 
+#ifdef __SMP__
+#if defined __i386__
+extern unsigned int num_processors;	/* arch/i386/kernel/smp.c */
+#elif defined __alpha__
+extern int smp_num_probed;	/* arch/alpha/kernel/smp.c */
+#elif defined __powerpc__
+extern int cpu_nr;		/* arch/ppc/kernel/smp.c */
+#endif
+
+extern int smp_num_cpus;	/* arch/<all>/kernel/smp.c */
+#endif /* __SMP__ */
+
+#ifdef __i386__
+extern unsigned long cpu_hz;	/* arch/i386/kernel/time.c */
+#endif
+
 #ifdef CONFIG_KMOD
 extern char modprobe_path[];
 #endif
@@ -153,6 +176,21 @@
 	{0}
 };
 
+/* static values */
+static int arg_max = ARG_MAX;
+static int child_max = CHILD_MAX; /* from limits.h, but is there really a limit? */
+static int clk_tck = HZ;
+static int ngroups_max = NGROUPS;
+static int open_max = NR_OPEN;
+static int supp = 1;
+static int not_supp = 0;
+static int one = 1;
+static int page_size = PAGE_SIZE;
+static int delaytimer_max = DELAYTIMER_MAX;
+static int timer_max = TIMER_MAX;
+static int iov_max = UIO_MAXIOV;
+static int rtsig_max = SIGRTMAX - SIGRTMIN + 1;
+
 static ctl_table kern_table[] = {
 	{KERN_OSTYPE, "ostype", system_utsname.sysname, 64,
 	 0444, NULL, &proc_doutsstring, &sysctl_string},
@@ -200,16 +238,96 @@
 	{KERN_ACCT, "acct", &acct_parm, 3*sizeof(int),
 	0644, NULL, &proc_dointvec},
 #endif
-	{KERN_RTSIGNR, "rtsig-nr", &nr_queued_signals, sizeof(int),
-	 0444, NULL, &proc_dointvec},
-	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
+	{KERN_SIGQUEUE_MAX, "sigqueue-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
+	{KERN_SIGQUEUE_NR, "sigqueue-nr", &nr_queued_signals, sizeof(int),
+	 0444, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
 	{KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
 	 0644, NULL, &proc_dointvec},
 #endif
 	{KERN_MAX_THREADS, "threads-max", &max_threads, sizeof(int),
 	 0644, NULL, &proc_dointvec},
+	{KERN_ARG_MAX, "arg-max", &arg_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_CHILD_MAX, "child-max", &child_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_CLK_TCK, "clk-tck", &clk_tck, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_NGROUPS_MAX, "ngroups-max", &ngroups_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_OPEN_MAX, "open-max", &open_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_JOB_CONTROL, "job-control", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_SAVED_IDS, "saved-ids", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_PAGE_SIZE, "page-size", &page_size, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_NPROCESSORS_CONF, "nprocessors-conf",
+#ifdef __SMP__
+#if defined __i386__
+	 &num_processors,
+#elif defined __sparc__
+	 &linux_num_cpus,
+#elif defined __alpha__
+	 &smp_num_probed,
+#elif defined __powerpc__
+	 &cpu_nr,
+#elif
+#error "smp not supported for this platform"
+#endif /* various platforms */
+#else  /* !__SMP__ */
+	 &one,
+#endif /* !__SMP__ */
+	 sizeof(int), 0444, NULL, &proc_dointvec},
+	{KERN_NPROCESSORS_ONLN, "nprocessors-onln",
+#ifdef __SMP__
+	 &smp_num_cpus,
+#else
+	 &one,
+#endif
+	 sizeof(int), 0444, NULL, &proc_dointvec},
+	{KERN_ASYNCHRONOUS_IO, "asynchronous-io", &not_supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_FSYNC, "fsync", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_MAPPED_FILES, "mapped-files", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_MEMLOCK, "memlock", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_MEMLOCK_RANGE, "memlock-range", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_MEMORY_PROTECTION, "memory-protection", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_MESSAGE_PASSING, "message-passing", &not_supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_PRIORITIZED_IO, "prioritized-io", &not_supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_PRIORITY_SCHEDULING, "priority-scheduling", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_REALTIME_SIGNALS, "realtime-signals", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_SEMAPHORES, "semaphores", &not_supp, sizeof(int),
+	 0444, NULL, &proc_dointvec}, 
+	{KERN_SHARED_MEMORY_OBJECTS, "shared-memory-objects", &not_supp,
+	 sizeof(int), 0444, NULL, &proc_dointvec},
+	{KERN_SYNCHRONIZED_IO, "synchronized-io", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_TIMERS, "timers", &supp, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_DELAYTIMER_MAX, "delaytimer-max", &delaytimer_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_TIMER_MAX, "timer-max", &timer_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_IOV_MAX, "iov-max", &iov_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+	{KERN_RTSIG_MAX, "rtsig-max", &rtsig_max, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+#ifdef __i386__
+	{KERN_LINUX_COUNTER_HZ, "linux-counter-hz", &cpu_hz, sizeof(int),
+	 0444, NULL, &proc_dointvec},
+#endif
 	{0}
 };
 
