use netbsd <sys/signal.h> and sigset_t
. create signals-related struct message type to store sigset_t directly . create notify-specific message types, so the generic NOTIFY_ARG doesn't exist anymore . various related test expansions, improvements, fixes . add a few error-checks to sigismember() calls . rename kernel call specific signals fields to SYS_* Change-Id: I53c18999b5eaf0cfa0cb25f5330bee9e7ad2b478
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel/kernel.h"
|
||||
#include "vm.h"
|
||||
@@ -98,16 +99,19 @@ static void set_idle_name(char * name, int n)
|
||||
#define PICK_HIGHERONLY 2
|
||||
|
||||
#define BuildNotifyMessage(m_ptr, src, dst_ptr) \
|
||||
memset((m_ptr), 0, sizeof(*(m_ptr))); \
|
||||
(m_ptr)->m_type = NOTIFY_MESSAGE; \
|
||||
(m_ptr)->NOTIFY_TIMESTAMP = get_monotonic(); \
|
||||
switch (src) { \
|
||||
case HARDWARE: \
|
||||
(m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_int_pending; \
|
||||
(m_ptr)->NOTIFY_INTMASK = priv(dst_ptr)->s_int_pending; \
|
||||
priv(dst_ptr)->s_int_pending = 0; \
|
||||
break; \
|
||||
case SYSTEM: \
|
||||
(m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_sig_pending; \
|
||||
priv(dst_ptr)->s_sig_pending = 0; \
|
||||
memcpy(&(m_ptr)->NOTIFY_SIGSET, \
|
||||
&priv(dst_ptr)->s_sig_pending, \
|
||||
sizeof(sigset_t)); \
|
||||
sigemptyset(&priv(dst_ptr)->s_sig_pending); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
@@ -408,6 +408,7 @@ int sig_nr; /* signal to be sent */
|
||||
register struct proc *rp, *sig_mgr_rp;
|
||||
endpoint_t sig_mgr;
|
||||
int sig_mgr_proc_nr;
|
||||
int s;
|
||||
|
||||
/* Lookup signal manager. */
|
||||
rp = proc_addr(proc_nr);
|
||||
@@ -438,8 +439,10 @@ int sig_nr; /* signal to be sent */
|
||||
return;
|
||||
}
|
||||
|
||||
if((s = sigismember(&rp->p_pending, sig_nr)) < 0)
|
||||
panic("sigismember failed");
|
||||
/* Check if the signal is already pending. Process it otherwise. */
|
||||
if (! sigismember(&rp->p_pending, sig_nr)) {
|
||||
if (!s) {
|
||||
sigaddset(&rp->p_pending, sig_nr);
|
||||
increase_proc_signals(rp);
|
||||
if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */
|
||||
|
||||
@@ -24,7 +24,7 @@ int do_endksig(struct proc * caller, message * m_ptr)
|
||||
/* Get process pointer and verify that it had signals pending. If the
|
||||
* process is already dead its flags will be reset.
|
||||
*/
|
||||
if(!isokendpt(m_ptr->SIG_ENDPT, &proc_nr))
|
||||
if(!isokendpt(m_ptr->SYS_SIG_ENDPT, &proc_nr))
|
||||
return EINVAL;
|
||||
|
||||
rp = proc_addr(proc_nr);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* m_type: SYS_GETKSIG
|
||||
*
|
||||
* The parameters for this kernel call are:
|
||||
* m2_i1: SIG_ENDPT # process with pending signals
|
||||
* m2_l1: SIG_MAP # bit map with pending signals
|
||||
* m2_i1: SYS_SIG_ENDPT # process with pending signals
|
||||
* m2_l1: SYS_SIG_MAP # bit map with pending signals
|
||||
*/
|
||||
|
||||
#include "kernel/system.h"
|
||||
@@ -28,8 +28,8 @@ int do_getksig(struct proc * caller, message * m_ptr)
|
||||
if (RTS_ISSET(rp, RTS_SIGNALED)) {
|
||||
if (caller->p_endpoint != priv(rp)->s_sig_mgr) continue;
|
||||
/* store signaled process' endpoint */
|
||||
m_ptr->SIG_ENDPT = rp->p_endpoint;
|
||||
m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */
|
||||
m_ptr->SYS_SIG_ENDPT = rp->p_endpoint;
|
||||
m_ptr->SYS_SIG_MAP = rp->p_pending; /* pending signals map */
|
||||
(void) sigemptyset(&rp->p_pending); /* clear map in the kernel */
|
||||
RTS_UNSET(rp, RTS_SIGNALED); /* blocked by SIG_PENDING */
|
||||
return(OK);
|
||||
@@ -37,7 +37,7 @@ int do_getksig(struct proc * caller, message * m_ptr)
|
||||
}
|
||||
|
||||
/* No process with pending signals was found. */
|
||||
m_ptr->SIG_ENDPT = NONE;
|
||||
m_ptr->SYS_SIG_ENDPT = NONE;
|
||||
return(OK);
|
||||
}
|
||||
#endif /* USE_GETKSIG */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* m_type: SYS_KILL
|
||||
*
|
||||
* The parameters for this kernel call are:
|
||||
* m2_i1: SIG_ENDPT # process to signal/ pending
|
||||
* m2_i2: SIG_NUMBER # signal number to send to process
|
||||
* m2_i1: SYS_SIG_ENDPT # process to signal/ pending
|
||||
* m2_i2: SYS_SIG_NUMBER # signal number to send to process
|
||||
*/
|
||||
|
||||
#include "kernel/system.h"
|
||||
@@ -23,9 +23,9 @@ int do_kill(struct proc * caller, message * m_ptr)
|
||||
* translated into an IPC message for system services.
|
||||
*/
|
||||
proc_nr_t proc_nr, proc_nr_e;
|
||||
int sig_nr = m_ptr->SIG_NUMBER;
|
||||
int sig_nr = m_ptr->SYS_SIG_NUMBER;
|
||||
|
||||
proc_nr_e= (proc_nr_t) m_ptr->SIG_ENDPT;
|
||||
proc_nr_e= (proc_nr_t) m_ptr->SYS_SIG_ENDPT;
|
||||
|
||||
if (!isokendpt(proc_nr_e, &proc_nr)) return(EINVAL);
|
||||
if (sig_nr >= _NSIG) return(EINVAL);
|
||||
|
||||
@@ -25,12 +25,12 @@ int do_sigreturn(struct proc * caller, message * m_ptr)
|
||||
register struct proc *rp;
|
||||
int proc_nr, r;
|
||||
|
||||
if (! isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL);
|
||||
if (! isokendpt(m_ptr->SYS_SIG_ENDPT, &proc_nr)) return(EINVAL);
|
||||
if (iskerneln(proc_nr)) return(EPERM);
|
||||
rp = proc_addr(proc_nr);
|
||||
|
||||
/* Copy in the sigcontext structure. */
|
||||
if((r=data_copy(m_ptr->SIG_ENDPT, (vir_bytes) m_ptr->SIG_CTXT_PTR,
|
||||
if((r=data_copy(m_ptr->SYS_SIG_ENDPT, (vir_bytes) m_ptr->SYS_SIG_CTXT_PTR,
|
||||
KERNEL, (vir_bytes) &sc, sizeof(struct sigcontext))) != OK)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* m_type: SYS_SIGSEND
|
||||
*
|
||||
* The parameters for this kernel call are:
|
||||
* m2_i1: SIG_ENDPT # process to call signal handler
|
||||
* m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure
|
||||
* m2_i3: SIG_FLAGS # flags for S_SIGRETURN call
|
||||
* m2_i1: SYS_SIG_ENDPT # process to call signal handler
|
||||
* m2_p1: SYS_SIG_CTXT_PTR # pointer to sigcontext structure
|
||||
* m2_i3: SYS_SIG_FLAGS # flags for S_SIGRETURN call
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -27,13 +27,13 @@ int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
struct sigframe fr, *frp;
|
||||
int proc_nr, r;
|
||||
|
||||
if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL);
|
||||
if (!isokendpt(m_ptr->SYS_SIG_ENDPT, &proc_nr)) return(EINVAL);
|
||||
if (iskerneln(proc_nr)) return(EPERM);
|
||||
rp = proc_addr(proc_nr);
|
||||
|
||||
/* Get the sigmsg structure into our address space. */
|
||||
if((r=data_copy_vmcheck(caller, caller->p_endpoint,
|
||||
(vir_bytes) m_ptr->SIG_CTXT_PTR, KERNEL, (vir_bytes) &smsg,
|
||||
(vir_bytes) m_ptr->SYS_SIG_CTXT_PTR, KERNEL, (vir_bytes) &smsg,
|
||||
(phys_bytes) sizeof(struct sigmsg))) != OK)
|
||||
return r;
|
||||
|
||||
@@ -64,7 +64,7 @@ int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
sc.sc_flags = rp->p_misc_flags & MF_FPU_INITIALIZED;
|
||||
|
||||
/* Copy the sigcontext structure to the user's stack. */
|
||||
if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &sc, m_ptr->SIG_ENDPT,
|
||||
if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &sc, m_ptr->SYS_SIG_ENDPT,
|
||||
(vir_bytes) scp, (vir_bytes) sizeof(struct sigcontext))) != OK)
|
||||
return r;
|
||||
|
||||
@@ -97,7 +97,7 @@ int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Copy the sigframe structure to the user's stack. */
|
||||
if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &fr,
|
||||
m_ptr->SIG_ENDPT, (vir_bytes) frp,
|
||||
m_ptr->SYS_SIG_ENDPT, (vir_bytes) frp,
|
||||
(vir_bytes) sizeof(struct sigframe))) != OK)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user