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, &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 */
 


More information about the freebsd-bugs mailing list