Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_sig.c
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
#include <sys/limits.h> | #include <sys/limits.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/refcount.h> | #include <sys/refcount.h> | ||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/procdesc.h> | #include <sys/procdesc.h> | ||||
#include <sys/ptrace.h> | |||||
#include <sys/posix4.h> | #include <sys/posix4.h> | ||||
#include <sys/pioctl.h> | #include <sys/pioctl.h> | ||||
#include <sys/racct.h> | #include <sys/racct.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/sdt.h> | #include <sys/sdt.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/sleepqueue.h> | #include <sys/sleepqueue.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
▲ Show 20 Lines • Show All 1,171 Lines • ▼ Show 20 Lines | kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, | ||||
struct timespec *timeout) | struct timespec *timeout) | ||||
{ | { | ||||
struct sigacts *ps; | struct sigacts *ps; | ||||
sigset_t saved_mask, new_block; | sigset_t saved_mask, new_block; | ||||
struct proc *p; | struct proc *p; | ||||
int error, sig, timo, timevalid = 0; | int error, sig, timo, timevalid = 0; | ||||
struct timespec rts, ets, ts; | struct timespec rts, ets, ts; | ||||
struct timeval tv; | struct timeval tv; | ||||
bool traced; | |||||
p = td->td_proc; | p = td->td_proc; | ||||
error = 0; | error = 0; | ||||
ets.tv_sec = 0; | ets.tv_sec = 0; | ||||
ets.tv_nsec = 0; | ets.tv_nsec = 0; | ||||
traced = false; | |||||
if (timeout != NULL) { | if (timeout != NULL) { | ||||
if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) { | if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) { | ||||
timevalid = 1; | timevalid = 1; | ||||
getnanouptime(&rts); | getnanouptime(&rts); | ||||
timespecadd(&rts, timeout, &ets); | timespecadd(&rts, timeout, &ets); | ||||
} | } | ||||
} | } | ||||
Show All 36 Lines | if (timeout != NULL) { | ||||
} | } | ||||
timespecsub(&ets, &rts, &ts); | timespecsub(&ets, &rts, &ts); | ||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
timo = tvtohz(&tv); | timo = tvtohz(&tv); | ||||
} else { | } else { | ||||
timo = 0; | timo = 0; | ||||
} | } | ||||
if (traced) { | |||||
error = EINTR; | |||||
break; | |||||
} | |||||
error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", timo); | error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", timo); | ||||
if (timeout != NULL) { | if (timeout != NULL) { | ||||
if (error == ERESTART) { | if (error == ERESTART) { | ||||
/* Timeout can not be restarted. */ | /* Timeout can not be restarted. */ | ||||
error = EINTR; | error = EINTR; | ||||
} else if (error == EAGAIN) { | } else if (error == EAGAIN) { | ||||
/* We will calculate timeout by ourself. */ | /* We will calculate timeout by ourself. */ | ||||
error = 0; | error = 0; | ||||
} | } | ||||
} | } | ||||
/* | |||||
* If PTRACE_SCE or PTRACE_SCX were set after | |||||
* userspace entered the syscall, return spurious | |||||
* EINTR after wait was done. Only do this as last | |||||
* resort after rechecking for possible queued signals | |||||
* and expired timeouts. | |||||
*/ | |||||
if (error == 0 && (p->p_ptevents & PTRACE_SYSCALL) != 0) | |||||
traced = true; | |||||
} | } | ||||
new_block = saved_mask; | new_block = saved_mask; | ||||
SIGSETNAND(new_block, td->td_sigmask); | SIGSETNAND(new_block, td->td_sigmask); | ||||
td->td_sigmask = saved_mask; | td->td_sigmask = saved_mask; | ||||
/* | /* | ||||
* Fewer signals can be delivered to us, reschedule signal | * Fewer signals can be delivered to us, reschedule signal | ||||
* notification. | * notification. | ||||
▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause", | ||||
/* void */; | /* void */; | ||||
thread_suspend_check(0); | thread_suspend_check(0); | ||||
mtx_lock(&p->p_sigacts->ps_mtx); | mtx_lock(&p->p_sigacts->ps_mtx); | ||||
while ((sig = cursig(td)) != 0) { | while ((sig = cursig(td)) != 0) { | ||||
KASSERT(sig >= 0, ("sig %d", sig)); | KASSERT(sig >= 0, ("sig %d", sig)); | ||||
has_sig += postsig(sig); | has_sig += postsig(sig); | ||||
} | } | ||||
mtx_unlock(&p->p_sigacts->ps_mtx); | mtx_unlock(&p->p_sigacts->ps_mtx); | ||||
/* | |||||
* If PTRACE_SCE or PTRACE_SCX were set after | |||||
* userspace entered the syscall, return spurious | |||||
* EINTR. | |||||
*/ | |||||
if ((p->p_ptevents & PTRACE_SYSCALL) != 0) | |||||
has_sig += 1; | |||||
} | } | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
td->td_errno = EINTR; | td->td_errno = EINTR; | ||||
td->td_pflags |= TDP_NERRNO; | td->td_pflags |= TDP_NERRNO; | ||||
return (EJUSTRETURN); | return (EJUSTRETURN); | ||||
} | } | ||||
#ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */ | #ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */ | ||||
▲ Show 20 Lines • Show All 2,329 Lines • Show Last 20 Lines |