1 /* The kernel call that is implemented in this file:
4 * The parameters for this kernel call are:
5 * m2_i1: SIG_ENDPT # process to call signal handler
6 * m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure
7 * m2_i3: SIG_FLAGS # flags for S_SIGRETURN call
11 #include "kernel/system.h"
17 /*===========================================================================*
19 *===========================================================================*/
20 int do_sigsend(struct proc
* caller
, message
* m_ptr
)
22 /* Handle sys_sigsend, POSIX-style signal handling. */
25 register struct proc
*rp
;
26 struct sigcontext sc
, *scp
;
27 struct sigframe fr
, *frp
;
30 if (!isokendpt(m_ptr
->SIG_ENDPT
, &proc_nr
)) return(EINVAL
);
31 if (iskerneln(proc_nr
)) return(EPERM
);
32 rp
= proc_addr(proc_nr
);
34 /* Get the sigmsg structure into our address space. */
35 if((r
=data_copy_vmcheck(caller
, caller
->p_endpoint
,
36 (vir_bytes
) m_ptr
->SIG_CTXT_PTR
, KERNEL
, (vir_bytes
) &smsg
,
37 (phys_bytes
) sizeof(struct sigmsg
))) != OK
)
40 /* Compute the user stack pointer where sigcontext will be stored. */
41 smsg
.sm_stkptr
= arch_get_sp(rp
);
42 scp
= (struct sigcontext
*) smsg
.sm_stkptr
- 1;
44 /* Copy the registers to the sigcontext structure. */
45 memcpy(&sc
.sc_regs
, (char *) &rp
->p_reg
, sizeof(sigregs
));
47 if(proc_used_fpu(rp
)) {
48 /* save the FPU context before saving it to the sig context */
50 memcpy(&sc
.sc_fpu_state
, rp
->p_seg
.fpu_state
, FPU_XFP_SIZE
);
54 /* Finish the sigcontext initialization. */
55 sc
.sc_mask
= smsg
.sm_mask
;
56 sc
.sc_flags
= rp
->p_misc_flags
& MF_FPU_INITIALIZED
;
58 /* Copy the sigcontext structure to the user's stack. */
59 if((r
=data_copy_vmcheck(caller
, KERNEL
, (vir_bytes
) &sc
, m_ptr
->SIG_ENDPT
,
60 (vir_bytes
) scp
, (vir_bytes
) sizeof(struct sigcontext
))) != OK
)
63 /* Initialize the sigframe structure. */
64 frp
= (struct sigframe
*) scp
- 1;
66 fr
.sf_retadr2
= (void (*)()) rp
->p_reg
.pc
;
67 fr
.sf_fp
= rp
->p_reg
.fp
;
68 rp
->p_reg
.fp
= (reg_t
) &frp
->sf_fp
;
71 fpu_sigcontext(rp
, &fr
, &sc
);
73 fr
.sf_signo
= smsg
.sm_signo
;
74 fr
.sf_retadr
= (void (*)()) smsg
.sm_sigreturn
;
76 /* Copy the sigframe structure to the user's stack. */
77 if((r
=data_copy_vmcheck(caller
, KERNEL
, (vir_bytes
) &fr
,
78 m_ptr
->SIG_ENDPT
, (vir_bytes
) frp
,
79 (vir_bytes
) sizeof(struct sigframe
))) != OK
)
82 /* Reset user registers to execute the signal handler. */
83 rp
->p_reg
.sp
= (reg_t
) frp
;
84 rp
->p_reg
.pc
= (reg_t
) smsg
.sm_sighandler
;
86 /* Signal handler should get clean FPU. */
87 rp
->p_misc_flags
&= ~MF_FPU_INITIALIZED
;
89 if(!RTS_ISSET(rp
, RTS_PROC_STOP
)) {
90 printf("system: warning: sigsend a running process\n");
91 printf("caller stack: ");
92 proc_stacktrace(caller
);
98 #endif /* USE_SIGSEND */