From owner-freebsd-bugs@FreeBSD.ORG Sat Feb 11 21:21:14 2006 Return-Path: X-Original-To: freebsd-bugs@FreeBSD.org Delivered-To: freebsd-bugs@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 005BC16A420; Sat, 11 Feb 2006 21:21:13 +0000 (GMT) (envelope-from hostmaster@GTS.NET) Received: from fukspam.GTS.NET (uucp.gts.net [204.138.66.129]) by mx1.FreeBSD.org (Postfix) with ESMTP id 16C4443D4C; Sat, 11 Feb 2006 21:21:10 +0000 (GMT) (envelope-from hostmaster@GTS.NET) Received: from localhost by fukspam.GTS.NET via sendmail with STDIO (/R:inet_hosts/T:inet_zone_smtp/dest:remote) id (8538 bytes from ident using UNIX) for ; Sat, 11 Feb 2006 16:21:08 -0500 (EST) (Smail-3.2.0.122-Pre 2005-Nov-17 #5; built 2006-Jan-31) Message-Id: From: hotlips Internet admin To: FreeBSD-gnats-submit@FreeBSD.org Date: Sat, 11 Feb 2006 16:21:07 -0500 (EST) In-Reply-To: <200602112100.k1BL0Jt5008826@freefall.freebsd.org> from "FreeBSD-gnats-submit@FreeBSD.org" at Feb 11, 2006 09:00:19 PM X-Mailer: ELM [version 2.5 PL6] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: freebsd-bugs@FreeBSD.org Subject: Re: misc/93199: missing linux rt_sigtimedwait system call X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Feb 2006 21:21:14 -0000 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 #include +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 */