- 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
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112893
@ -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.
|
* in scope (in the current implementation), so we can't use it here.
|
||||||
*/
|
*/
|
||||||
int sigqueue(__pid_t, int, const union sigval);
|
int sigqueue(__pid_t, int, const union sigval);
|
||||||
|
#endif
|
||||||
struct timespec;
|
struct timespec;
|
||||||
int sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict,
|
int sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict,
|
||||||
const struct timespec * __restrict);
|
const struct timespec * __restrict);
|
||||||
int sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict);
|
int sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __XSI_VISIBLE
|
#if __XSI_VISIBLE
|
||||||
int killpg(__pid_t, int);
|
int killpg(__pid_t, int);
|
||||||
|
@ -89,6 +89,10 @@ static int filt_sigattach(struct knote *kn);
|
|||||||
static void filt_sigdetach(struct knote *kn);
|
static void filt_sigdetach(struct knote *kn);
|
||||||
static int filt_signal(struct knote *kn, long hint);
|
static int filt_signal(struct knote *kn, long hint);
|
||||||
static struct thread *sigtd(struct proc *p, int sig, int prop);
|
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 =
|
struct filterops sig_filtops =
|
||||||
{ 0, filt_sigattach, filt_sigdetach, filt_signal };
|
{ 0, filt_sigattach, filt_sigdetach, filt_signal };
|
||||||
@ -592,7 +596,7 @@ execsigs(p)
|
|||||||
*
|
*
|
||||||
* Manipulate signal mask.
|
* Manipulate signal mask.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
do_sigprocmask(td, how, set, oset, old)
|
do_sigprocmask(td, how, set, oset, old)
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
int how;
|
int how;
|
||||||
@ -694,9 +698,177 @@ osigprocmask(td, uap)
|
|||||||
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
struct sigpending_args {
|
struct sigpending_args {
|
||||||
|
SIGSETOR(siglist, td->td_siglist);
|
||||||
sigset_t *set;
|
sigset_t *set;
|
||||||
};
|
};
|
||||||
#endif
|
#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
|
* MPSAFE
|
||||||
*/
|
*/
|
||||||
|
@ -494,8 +494,10 @@
|
|||||||
struct sigaction *oact); }
|
struct sigaction *oact); }
|
||||||
343 MSTD POSIX { int sigpending(sigset_t *set); }
|
343 MSTD POSIX { int sigpending(sigset_t *set); }
|
||||||
344 MCOMPAT4 BSD { int sigreturn(const struct ucontext4 *sigcntxp); }
|
344 MCOMPAT4 BSD { int sigreturn(const struct ucontext4 *sigcntxp); }
|
||||||
345 UNIMPL NOHIDE sigtimedwait
|
345 MSTD NOHIDE { int sigtimedwait(const sigset_t *set, \
|
||||||
346 UNIMPL NOHIDE sigwaitinfo
|
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, \
|
347 MSTD BSD { int __acl_get_file(const char *path, \
|
||||||
acl_type_t type, struct acl *aclp); }
|
acl_type_t type, struct acl *aclp); }
|
||||||
348 MSTD BSD { int __acl_set_file(const char *path, \
|
348 MSTD BSD { int __acl_set_file(const char *path, \
|
||||||
@ -621,6 +623,7 @@
|
|||||||
acl_type_t type); }
|
acl_type_t type); }
|
||||||
428 MSTD BSD { int __acl_aclcheck_link(const char *path, \
|
428 MSTD BSD { int __acl_aclcheck_link(const char *path, \
|
||||||
acl_type_t type, struct acl *aclp); }
|
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:
|
; Please copy any additions and changes to the following compatability tables:
|
||||||
; sys/ia64/ia32/syscalls.master (take a best guess)
|
; 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 siginit(struct proc *p);
|
||||||
void signotify(struct thread *td);
|
void signotify(struct thread *td);
|
||||||
void trapsignal(struct thread *td, int sig, u_long code);
|
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);
|
int sig_ffs(sigset_t *set);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user