diff options
-rw-r--r-- | sys/amd64/ia32/ia32_signal.c | 26 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 90 | ||||
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 9 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_genassym.c | 1 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_signal.h | 50 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_sysvec.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 4 | ||||
-rw-r--r-- | sys/sys/signalvar.h | 2 |
8 files changed, 105 insertions, 80 deletions
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index a29abf0..1d693b4 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_object.h> #include <vm/vm_extern.h> +#include <compat/freebsd32/freebsd32_signal.h> #include <compat/freebsd32/freebsd32_util.h> #include <compat/freebsd32/freebsd32_proto.h> #include <compat/ia32/ia32_signal.h> @@ -298,7 +299,7 @@ static void freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct ia32_sigframe4 sf, *sfp; - struct ia32_siginfo siginfo; + struct siginfo32 siginfo; struct proc *p; struct thread *td; struct sigacts *psp; @@ -308,7 +309,7 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) td = curthread; p = td->td_proc; - siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo); + siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); PROC_LOCK_ASSERT(p, MA_OWNED); sig = siginfo.si_signo; @@ -407,7 +408,7 @@ void ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct ia32_sigframe sf, *sfp; - struct ia32_siginfo siginfo; + struct siginfo32 siginfo; struct proc *p; struct thread *td; struct sigacts *psp; @@ -416,7 +417,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) int oonstack; int sig; - siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo); + siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); @@ -741,20 +742,3 @@ ia32_setregs(td, entry, stack, ps_strings) pcb->pcb_flags |= PCB_FULLCTX; td->td_retval[1] = 0; } - -void -siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst) -{ - dst->si_signo = src->si_signo; - dst->si_errno = src->si_errno; - dst->si_code = src->si_code; - dst->si_pid = src->si_pid; - dst->si_uid = src->si_uid; - dst->si_status = src->si_status; - dst->si_addr = dst->si_addr; - dst->si_value.sigval_int = src->si_value.sival_int; - dst->si_band = src->si_band; - dst->si_trapno = src->si_trapno; - dst->si_timerid = src->si_timerid; - dst->si_overrun = src->si_overrun; -} diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 461e8c0..41cb789 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$"); #include <compat/freebsd32/freebsd32_util.h> #include <compat/freebsd32/freebsd32.h> +#include <compat/freebsd32/freebsd32_signal.h> #include <compat/freebsd32/freebsd32_proto.h> CTASSERT(sizeof(struct timeval32) == 8); @@ -192,12 +193,6 @@ freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfss } #endif -struct sigaltstack32 { - u_int32_t ss_sp; - u_int32_t ss_size; - int ss_flags; -}; - CTASSERT(sizeof(struct sigaltstack32) == 12); int @@ -2178,6 +2173,89 @@ freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap) return (kern_thr_suspend(td, tsp)); } +void +siginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst) +{ + bzero(dst, sizeof(*dst)); + dst->si_signo = src->si_signo; + dst->si_errno = src->si_errno; + dst->si_code = src->si_code; + dst->si_pid = src->si_pid; + dst->si_uid = src->si_uid; + dst->si_status = src->si_status; + dst->si_addr = dst->si_addr; + dst->si_value.sigval_int = src->si_value.sival_int; + dst->si_timerid = src->si_timerid; + dst->si_overrun = src->si_overrun; +} + +int +freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) +{ + struct timespec32 ts32; + struct timespec ts; + struct timespec *timeout; + sigset_t set; + ksiginfo_t ksi; + struct siginfo32 si32; + int error; + + if (uap->timeout) { + error = copyin(uap->timeout, &ts32, sizeof(ts32)); + if (error) + return (error); + ts.tv_sec = ts32.tv_sec; + ts.tv_nsec = ts32.tv_nsec; + timeout = &ts; + } else + timeout = NULL; + + error = copyin(uap->set, &set, sizeof(set)); + if (error) + return (error); + + error = kern_sigtimedwait(td, set, &ksi, timeout); + if (error) + return (error); + + if (uap->info) { + siginfo_to_siginfo32(&ksi.ksi_info, &si32); + error = copyout(&si32, uap->info, sizeof(struct siginfo32)); + } + + if (error == 0) + td->td_retval[0] = ksi.ksi_signo; + return (error); +} + +/* + * MPSAFE + */ +int +freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap) +{ + ksiginfo_t ksi; + struct siginfo32 si32; + sigset_t set; + int error; + + error = copyin(uap->set, &set, sizeof(set)); + if (error) + return (error); + + error = kern_sigtimedwait(td, set, &ksi, NULL); + if (error) + return (error); + + if (uap->info) { + siginfo_to_siginfo32(&ksi.ksi_info, &si32); + error = copyout(&si32, uap->info, sizeof(struct siginfo32)); + } + if (error == 0) + td->td_retval[0] = ksi.ksi_signo; + return (error); +} + #if 0 int diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index ceed358..5cfd0c8 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -578,10 +578,11 @@ 343 AUE_SIGPENDING NOPROTO { int sigpending(sigset_t *set); } 344 AUE_SIGRETURN COMPAT4 { int freebsd32_sigreturn( \ const struct freebsd4_freebsd32_ucontext *sigcntxp); } -; XXX implement -345 AUE_SIGWAIT UNIMPL sigtimedwait -; XXX implement -346 AUE_NULL UNIMPL sigwaitinfo +345 AUE_SIGWAIT STD { int freebsd32_sigtimedwait(const sigset_t *set, \ + siginfo_t *info, \ + const struct timespec *timeout); } +346 AUE_NULL STD { int freebsd32_sigwaitinfo(const sigset_t *set, \ + siginfo_t *info); } 347 AUE_NULL NOPROTO { int __acl_get_file(const char *path, \ acl_type_t type, struct acl *aclp); } 348 AUE_NULL NOPROTO { int __acl_set_file(const char *path, \ diff --git a/sys/compat/ia32/ia32_genassym.c b/sys/compat/ia32/ia32_genassym.c index 54cec21..84fb648 100644 --- a/sys/compat/ia32/ia32_genassym.c +++ b/sys/compat/ia32/ia32_genassym.c @@ -8,6 +8,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/signal.h> +#include <compat/freebsd32/freebsd32_signal.h> #include <compat/ia32/ia32_signal.h> ASSYM(IA32_SIGF_HANDLER, offsetof(struct ia32_sigframe, sf_ah)); diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h index 8868a7e..f2be96d 100644 --- a/sys/compat/ia32/ia32_signal.h +++ b/sys/compat/ia32/ia32_signal.h @@ -29,12 +29,6 @@ * $FreeBSD$ */ -struct ia32_sigaltstack { - u_int32_t ss_sp; /* signal stack base */ - u_int32_t ss_size; /* signal stack length */ - int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ -}; - struct ia32_mcontext { u_int32_t mc_onstack; /* XXX - sigcontext compat. */ u_int32_t mc_gs; /* machine state (struct trapframe) */ @@ -72,7 +66,7 @@ struct ia32_ucontext { sigset_t uc_sigmask; struct ia32_mcontext uc_mcontext; u_int32_t uc_link; - struct ia32_sigaltstack uc_stack; + struct sigaltstack32 uc_stack; u_int32_t uc_flags; u_int32_t __spare__[4]; }; @@ -108,7 +102,7 @@ struct ia32_ucontext4 { sigset_t uc_sigmask; struct ia32_mcontext4 uc_mcontext; u_int32_t uc_link; - struct ia32_sigaltstack uc_stack; + struct sigaltstack32 uc_stack; u_int32_t __spare__[8]; }; #endif @@ -142,39 +136,6 @@ struct ia32_sigcontext3 { /* * Signal frames, arguments passed to application signal handlers. */ -union ia32_sigval { - int sigval_int; - u_int32_t sigval_ptr; -}; -struct ia32_siginfo { - int si_signo; /* signal number */ - int si_errno; /* errno association */ - int si_code; /* signal code */ - int32_t si_pid; /* sending process */ - u_int32_t si_uid; /* sender's ruid */ - int si_status; /* exit value */ - u_int32_t si_addr; /* faulting instruction */ - union ia32_sigval si_value; /* signal value */ - union { - struct { - int _trapno;/* machine specific trap code */ - } _fault; - struct { - int _timerid; - int _overrun; - } _timer; - struct { - int _mqd; - } _mesgq; - struct { - int _band; /* band event for SIGPOLL */ - } _poll; /* was this ever used ? */ - struct { - int __spare1__; - int __spare2__[7]; - } __spare__; - } _reason; -}; #ifdef COMPAT_FREEBSD4 struct ia32_sigframe4 { @@ -184,7 +145,7 @@ struct ia32_sigframe4 { u_int32_t sf_addr; /* undocumented 4th arg */ u_int32_t sf_ah; /* action/handler pointer */ struct ia32_ucontext4 sf_uc; /* = *sf_ucontext */ - struct ia32_siginfo sf_si; /* = *sf_siginfo (SA_SIGINFO case) */ + struct siginfo32 sf_si; /* = *sf_siginfo (SA_SIGINFO case) */ }; #endif @@ -196,7 +157,7 @@ struct ia32_sigframe { u_int32_t sf_ah; /* action/handler pointer */ /* Beware, hole due to ucontext being 16 byte aligned! */ struct ia32_ucontext sf_uc; /* = *sf_ucontext */ - struct ia32_siginfo sf_si; /* = *sf_siginfo (SA_SIGINFO case) */ + struct siginfo32 sf_si; /* = *sf_siginfo (SA_SIGINFO case) */ }; #ifdef COMPAT_FREEBSD3 @@ -204,7 +165,7 @@ struct ia32_siginfo3 { struct ia32_sigcontext3 si_sc; int si_signo; int si_code; - union ia32_sigval si_value; + union sigval32 si_value; }; struct ia32_sigframe3 { int sf_signum; @@ -224,4 +185,3 @@ extern int sz_freebsd4_ia32_sigcode; extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *); extern void ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings); -extern void siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst); diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index ede511d..b31400c 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_object.h> #include <vm/vm_extern.h> +#include <compat/freebsd32/freebsd32_signal.h> #include <compat/freebsd32/freebsd32_util.h> #include <compat/freebsd32/freebsd32_proto.h> #include <compat/freebsd32/freebsd32_syscall.h> @@ -85,7 +86,7 @@ __FBSDID("$FreeBSD$"); CTASSERT(sizeof(struct ia32_mcontext) == 640); CTASSERT(sizeof(struct ia32_ucontext) == 704); CTASSERT(sizeof(struct ia32_sigframe) == 800); -CTASSERT(sizeof(struct ia32_siginfo) == 64); +CTASSERT(sizeof(struct siginfo32) == 64); #ifdef COMPAT_FREEBSD4 CTASSERT(sizeof(struct ia32_mcontext4) == 260); CTASSERT(sizeof(struct ia32_ucontext4) == 324); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index b3cafca..d589188 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -94,8 +94,6 @@ 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 kern_sigtimedwait(struct thread *, sigset_t, - ksiginfo_t *, struct timespec *); static int do_tdsignal(struct proc *, struct thread *, int, ksiginfo_t *); static void sigqueue_start(void); @@ -1177,7 +1175,7 @@ sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap) return (error); } -static int +int kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, struct timespec *timeout) { diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index ee32b8d..e78358c 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -350,6 +350,8 @@ void sigqueue_move(struct sigqueue *, struct sigqueue *, int sig); void sigqueue_delete_set_proc(struct proc *, sigset_t *); void sigqueue_delete_stopmask_proc(struct proc *); void sigqueue_take(ksiginfo_t *ksi); +int kern_sigtimedwait(struct thread *, sigset_t, + ksiginfo_t *, struct timespec *); /* * Machine-dependent functions: |