misc/93199: missing linux rt_sigtimedwait system call
hotlips Internet admin
hostmaster at GTS.NET
Sat Feb 11 13:30:14 PST 2006
The following reply was made to PR misc/93199; it has been noted by GNATS.
From: hotlips Internet admin <hostmaster at GTS.NET>
To: FreeBSD-gnats-submit at FreeBSD.org
Cc: freebsd-bugs at FreeBSD.org
Subject: Re: misc/93199: missing linux rt_sigtimedwait system call
Date: Sat, 11 Feb 2006 16:21:07 -0500 (EST)
Thus saith FreeBSD-gnats-submit at 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 at 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, <v, 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 */
More information about the freebsd-bugs
mailing list