- Define sigwait, sigtimedwait, and sigwaitinfo in terms of
kern_sigtimedwait() which is capable of supporting all of their semantics. - These should be POSIX compliant but more careful review is needed before we announce this.
This commit is contained in:
parent
da4898b1d7
commit
a447cd8b28
@ -85,12 +85,12 @@ int sigwait(const sigset_t * __restrict, int * __restrict);
|
||||
* in scope (in the current implementation), so we can't use it here.
|
||||
*/
|
||||
int sigqueue(__pid_t, int, const union sigval);
|
||||
#endif
|
||||
struct timespec;
|
||||
int sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict,
|
||||
const struct timespec * __restrict);
|
||||
int sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __XSI_VISIBLE
|
||||
int killpg(__pid_t, int);
|
||||
|
@ -89,6 +89,10 @@ static int filt_sigattach(struct knote *kn);
|
||||
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 do_sigprocmask(struct thread *td, int how,
|
||||
sigset_t *set, sigset_t *oset, int old);
|
||||
static int kern_sigtimedwait(struct thread *td, sigset_t set,
|
||||
siginfo_t *info, struct timespec *timeout);
|
||||
|
||||
struct filterops sig_filtops =
|
||||
{ 0, filt_sigattach, filt_sigdetach, filt_signal };
|
||||
@ -592,7 +596,7 @@ execsigs(p)
|
||||
*
|
||||
* Manipulate signal mask.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
do_sigprocmask(td, how, set, oset, old)
|
||||
struct thread *td;
|
||||
int how;
|
||||
@ -694,9 +698,177 @@ osigprocmask(td, uap)
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct sigpending_args {
|
||||
SIGSETOR(siglist, td->td_siglist);
|
||||
sigset_t *set;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
sigwait(struct thread *td, struct sigwait_args *uap)
|
||||
{
|
||||
siginfo_t info;
|
||||
sigset_t set;
|
||||
int error;
|
||||
|
||||
error = copyin(uap->set, &set, sizeof(set));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = kern_sigtimedwait(td, set, &info, NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = copyout(&info.si_signo, uap->sig, sizeof(info.si_signo));
|
||||
/* Repost if we got an error. */
|
||||
if (error && info.si_signo)
|
||||
tdsignal(td, info.si_signo);
|
||||
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
sigtimedwait(struct thread *td, struct sigtimedwait_args *uap)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct timespec *timeout;
|
||||
sigset_t set;
|
||||
siginfo_t info;
|
||||
int error;
|
||||
|
||||
if (uap->timeout) {
|
||||
error = copyin(uap->timeout, &ts, sizeof(ts));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
timeout = &ts;
|
||||
} else
|
||||
timeout = NULL;
|
||||
|
||||
error = copyin(uap->set, &set, sizeof(set));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = kern_sigtimedwait(td, set, &info, timeout);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = copyout(&info, uap->info, sizeof(info));
|
||||
/* Repost if we got an error. */
|
||||
if (error && info.si_signo)
|
||||
tdsignal(td, info.si_signo);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap)
|
||||
{
|
||||
siginfo_t info;
|
||||
sigset_t set;
|
||||
int error;
|
||||
|
||||
error = copyin(uap->set, &set, sizeof(set));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = kern_sigtimedwait(td, set, &info, NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = copyout(&info, uap->info, sizeof(info));
|
||||
/* Repost if we got an error. */
|
||||
if (error && info.si_signo)
|
||||
tdsignal(td, info.si_signo);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
kern_sigtimedwait(struct thread *td, sigset_t set, siginfo_t *info,
|
||||
struct timespec *timeout)
|
||||
{
|
||||
register struct sigacts *ps;
|
||||
sigset_t oldmask;
|
||||
struct proc *p;
|
||||
int error;
|
||||
int sig;
|
||||
int hz;
|
||||
|
||||
p = td->td_proc;
|
||||
error = 0;
|
||||
sig = 0;
|
||||
SIG_CANTMASK(set);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
|
||||
ps = p->p_sigacts;
|
||||
oldmask = td->td_sigmask;
|
||||
td->td_sigmask = set;
|
||||
signotify(td);
|
||||
|
||||
sig = cursig(td);
|
||||
if (sig)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* POSIX says this must be checked after looking for pending
|
||||
* signals.
|
||||
*/
|
||||
if (timeout) {
|
||||
struct timeval tv;
|
||||
|
||||
if (timeout->tv_nsec > 1000000000) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
TIMESPEC_TO_TIMEVAL(&tv, timeout);
|
||||
hz = tvtohz(&tv);
|
||||
} else
|
||||
hz = 0;
|
||||
|
||||
error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "pause", hz);
|
||||
if (error == EINTR)
|
||||
error = 0;
|
||||
else if (error)
|
||||
goto out;
|
||||
|
||||
sig = cursig(td);
|
||||
out:
|
||||
td->td_sigmask = oldmask;
|
||||
if (sig) {
|
||||
sig_t action;
|
||||
|
||||
action = ps->ps_sigact[_SIG_IDX(sig)];
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(td, KTR_PSIG))
|
||||
ktrpsig(sig, action, td->td_flags & TDF_OLDMASK ?
|
||||
&td->td_oldsigmask : &td->td_sigmask, 0);
|
||||
#endif
|
||||
_STOPEVENT(p, S_SIG, sig);
|
||||
|
||||
if (action == SIG_DFL)
|
||||
sigexit(td, sig);
|
||||
/* NOTREACHED */
|
||||
|
||||
SIGDELSET(td->td_siglist, sig);
|
||||
info->si_signo = sig;
|
||||
info->si_code = 0;
|
||||
}
|
||||
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
|
@ -494,8 +494,10 @@
|
||||
struct sigaction *oact); }
|
||||
343 MSTD POSIX { int sigpending(sigset_t *set); }
|
||||
344 MCOMPAT4 BSD { int sigreturn(const struct ucontext4 *sigcntxp); }
|
||||
345 UNIMPL NOHIDE sigtimedwait
|
||||
346 UNIMPL NOHIDE sigwaitinfo
|
||||
345 MSTD NOHIDE { int sigtimedwait(const sigset_t *set, \
|
||||
siginfo_t *info, const struct timespec *timeout); }
|
||||
346 MSTD NOHIDE { int sigwaitinfo(const sigset_t *set, \
|
||||
siginfo_t *info); }
|
||||
347 MSTD BSD { int __acl_get_file(const char *path, \
|
||||
acl_type_t type, struct acl *aclp); }
|
||||
348 MSTD BSD { int __acl_set_file(const char *path, \
|
||||
@ -621,6 +623,7 @@
|
||||
acl_type_t type); }
|
||||
428 MSTD BSD { int __acl_aclcheck_link(const char *path, \
|
||||
acl_type_t type, struct acl *aclp); }
|
||||
429 MSTD NOHIDE { int sigwait(const sigset_t *set, int *sig); }
|
||||
|
||||
; Please copy any additions and changes to the following compatability tables:
|
||||
; sys/ia64/ia32/syscalls.master (take a best guess)
|
||||
|
@ -249,8 +249,6 @@ void sigexit(struct thread *td, int signum) __dead2;
|
||||
void siginit(struct proc *p);
|
||||
void signotify(struct thread *td);
|
||||
void trapsignal(struct thread *td, int sig, u_long code);
|
||||
int do_sigprocmask(struct thread *td, int how,
|
||||
sigset_t *set, sigset_t *oset, int old);
|
||||
int sig_ffs(sigset_t *set);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user