Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Feb 2006 16:21:07 -0500 (EST)
From:      hotlips Internet admin <hostmaster@GTS.NET>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        freebsd-bugs@FreeBSD.org
Subject:   Re: misc/93199: missing linux rt_sigtimedwait system call
Message-ID:  <m1F82B2-000BM1C@fukspam.GTS.NET>
In-Reply-To: <200602112100.k1BL0Jt5008826@freefall.freebsd.org> from "FreeBSD-gnats-submit@FreeBSD.org" at Feb 11, 2006 09:00:19 PM

next in thread | previous in thread | raw e-mail | index | archive | help
Thus saith FreeBSD-gnats-submit@FreeBSD.org:
| 
| Thank you very much for your problem report.
| It has the internal identification `misc/93199'.
| The individual assigned to look at your
| report is: freebsd-bugs. 
| 
| You can access the state of your problem report at any time
| via this link:
| 
| http://www.freebsd.org/cgi/query-pr.cgi?pr=93199
| 
| >Category:       misc
| >Responsible:    freebsd-bugs
| >Synopsis:       missing linux rt_sigtimedwait system call
| >Arrival-Date:   Sat Feb 11 21:00:18 GMT 2006


	below is a patchset to add linux rt_sigtimedwait system call
	(rt_sigpending is included as well)


-- 
Bruce Becker			+1 416 410 0879
GTS Network Administration	Toronto, Ont.
Email:	hostmaster@gts.net

 --------- 8< --------- 8< --------- 8< --------- 8< --------- 8< ---------

--- kern/kern_sig.c.2006012200	Sun Jan 22 20:11:45 2006
+++ kern/kern_sig.c	Tue Feb  7 23:14:12 2006
@@ -90,7 +90,7 @@
 static void	filt_sigdetach(struct knote *kn);
 static int	filt_signal(struct knote *kn, long hint);
 static struct thread *sigtd(struct proc *p, int sig, int prop);
-static int	kern_sigtimedwait(struct thread *td, sigset_t set,
+int		kern_sigtimedwait(struct thread *td, sigset_t set,
 				siginfo_t *info, struct timespec *timeout);
 static void	do_tdsignal(struct thread *td, int sig, sigtarget_t target);
 
@@ -838,7 +838,7 @@
 	return (error);
 }
 
-static int
+int
 kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
     struct timespec *timeout)
 {
--- compat/linux/linux_signal.c.2005021300	Sun Feb 13 14:50:57 2005
+++ compat/linux/linux_signal.c	Tue Feb  7 23:24:54 2006
@@ -50,6 +50,9 @@
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
 
+int	kern_sigtimedwait(struct thread *td, sigset_t set,
+			siginfo_t *info, struct timespec *timeout);
+
 void
 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
 {
@@ -407,6 +410,108 @@
 	return (copyout(&mask, args->mask, sizeof(mask)));
 }
 #endif	/*!__alpha__*/
+
+int
+linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
+{
+	struct proc *p = td->td_proc;
+	sigset_t bset;
+	l_sigset_t lset;
+
+#ifdef DEBUG
+	if (ldebug(rt_sigpending))
+		printf(ARGS(rt_sigpending, "*"));
+#endif
+	if (args->sigsetsize != sizeof(l_sigset_t))
+		return (EINVAL);
+	PROC_LOCK(p);
+	bset = p->p_siglist;
+	SIGSETOR(bset, td->td_siglist);
+	SIGSETAND(bset, td->td_sigmask);
+	PROC_UNLOCK(p);
+	bsd_to_linux_sigset(&bset, &lset);
+	return (copyout(&lset, args->set, sizeof(args->sigsetsize)));
+}
+
+int
+linux_rt_sigtimedwait(struct thread *td, struct linux_rt_sigtimedwait_args *args)
+{
+#ifdef DEBUG
+	struct proc *p = td->td_proc;
+#endif
+	int error;
+	l_timeval ltv;
+	struct timeval tv;
+	struct timespec ts, *tsa;
+	l_sigset_t lset;
+	sigset_t bset;
+	l_siginfo_t linfo;
+	siginfo_t info;
+
+#ifdef DEBUG
+	if (ldebug(rt_sigtimedwait))
+		printf(ARGS(rt_sigtimedwait, "*"));
+#endif
+	if (args->sigsetsize != sizeof(l_sigset_t))
+		return(EINVAL);
+
+	if ((error = copyin(args->set, &lset, sizeof(lset))))
+		return(error);
+	linux_to_bsd_sigset(&lset, &bset);
+
+	tsa = NULL;
+	if (args->timeout) {
+		if ((error = copyin(args->timeout, &ltv, sizeof(ltv))))
+			return(error);
+#ifdef DEBUG
+		printf("Linux-emul(%ld): incoming timeout (%ld/%ld)\n",
+			(long)p->p_pid, ltv.tv_sec, ltv.tv_usec);
+#endif
+		tv.tv_sec = (long)ltv.tv_sec;
+		tv.tv_usec = (suseconds_t)ltv.tv_usec;
+		if (itimerfix(&tv)) {
+			/* The timeout was invalid. Convert it to something
+			 * valid that will act as it does under Linux.
+			 */
+			tv.tv_sec += tv.tv_usec / 1000000;
+			tv.tv_usec %= 1000000;
+			if (tv.tv_usec < 0) {
+				tv.tv_sec -= 1;
+				tv.tv_usec += 1000000;
+			}
+			if (tv.tv_sec < 0)
+				timevalclear(&tv);
+#ifdef DEBUG
+			printf("Linux-emul(%ld): converted timeout (%ld/%ld)\n",
+				(long)p->p_pid, tv.tv_sec, tv.tv_usec);
+#endif
+		}
+		TIMEVAL_TO_TIMESPEC(&tv, &ts);
+		tsa = &ts;
+	}
+	error = kern_sigtimedwait(td, bset, &info, tsa);
+#ifdef DEBUG
+	printf("Linux-emul(%ld): sigtimedwait returning (%d)\n", (long)p->p_pid, error);
+#endif
+	if (error)
+		return error;
+
+	if (args->ptr) {
+		memset(&linfo, 0, sizeof(linfo));
+		linfo.lsi_signo = info.si_signo;
+		error = copyout(&linfo, args->ptr, sizeof(linfo));
+	}
+	/* Repost if we got an error. */
+	if (error && info.si_signo) {
+		PROC_LOCK(td->td_proc);
+		tdsignal(td, info.si_signo, SIGTARGET_TD);
+		PROC_UNLOCK(td->td_proc);
+	} else {
+		td->td_retval[0] = info.si_signo; 
+	}
+	return error;
+
+}
 
 int
 linux_kill(struct thread *td, struct linux_kill_args *args)
--- amd64/linux32/syscalls.master.2005072000	Wed Jul 20 13:42:14 2005
+++ amd64/linux32/syscalls.master	Tue Feb  7 12:33:56 2006
@@ -310,8 +310,11 @@
 175	AUE_NULL	MSTD	{ int linux_rt_sigprocmask(l_int how, \
 				    l_sigset_t *mask, l_sigset_t *omask, \
 				    l_size_t sigsetsize); }
-176	AUE_NULL	MSTD	{ int linux_rt_sigpending(void); }
-177	AUE_NULL	MSTD	{ int linux_rt_sigtimedwait(void); }
+176	AUE_NULL	MSTD	{ int linux_rt_sigpending((l_sigset_t *mask, \
+				    l_size_t sigsetsize); }
+177	AUE_NULL	MSTD	{ int linux_rt_sigtimedwait(l_sigset_t *mask, \
+				l_siginfo_t *ptr, struct timeval *tv, \
+				l_size_t sigsetsize); }
 178	AUE_NULL	MSTD	{ int linux_rt_sigqueueinfo(void); }
 179	AUE_NULL	MSTD	{ int linux_rt_sigsuspend( \
 				    l_sigset_t *newset, \
--- amd64/linux32/linux32_dummy.c.2004081600	Mon Aug 16 03:55:06 2004
+++ amd64/linux32/linux32_dummy.c	Tue Feb  7 12:34:44 2006
@@ -54,8 +54,6 @@
 DUMMY(query_module);
 DUMMY(nfsservctl);
 DUMMY(prctl);
-DUMMY(rt_sigpending);
-DUMMY(rt_sigtimedwait);
 DUMMY(rt_sigqueueinfo);
 DUMMY(capget);
 DUMMY(capset);
--- amd64/linux32/linux32_proto.h.2005072000	Wed Jul 20 13:43:52 2005
+++ amd64/linux32/linux32_proto.h	Tue Feb  7 21:22:56 2006
@@ -518,10 +518,14 @@
 	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigpending_args {
-	register_t dummy;
+	char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)];
+	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigtimedwait_args {
-	register_t dummy;
+	char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)];
+ 	char ptr_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * ptr; char ptr_r_[PADR_(l_siginfo_t *)];
+	char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)];
+	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigqueueinfo_args {
 	register_t dummy;
--- amd64/linux32/linux32_sysent.c.2005012200	Wed Jul 20 13:43:52 2005
+++ amd64/linux32/linux32_sysent.c	Tue Feb  7 14:38:28 2006
@@ -196,8 +196,8 @@
 	{ SYF_MPSAFE | AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn, AUE_NULL },	/* 173 = linux_rt_sigreturn */
 	{ SYF_MPSAFE | AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction, AUE_NULL },	/* 174 = linux_rt_sigaction */
 	{ SYF_MPSAFE | AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL },	/* 175 = linux_rt_sigprocmask */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigpending, AUE_NULL },	/* 176 = linux_rt_sigpending */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL },	/* 177 = linux_rt_sigtimedwait */
+	{ SYF_MPSAFE | AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL },	/* 176 = linux_rt_sigpending */
+	{ SYF_MPSAFE | AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL },	/* 177 = linux_rt_sigtimedwait */
 	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL },	/* 178 = linux_rt_sigqueueinfo */
 	{ SYF_MPSAFE | AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL },	/* 179 = linux_rt_sigsuspend */
 	{ SYF_MPSAFE | AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_NULL },	/* 180 = linux_pread */




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m1F82B2-000BM1C>