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 "../system.h"
14 #include <sys/sigcontext.h>
18 /*===========================================================================*
20 *===========================================================================*/
21 PUBLIC
int do_sigsend(m_ptr
)
22 message
*m_ptr
; /* pointer to request message */
24 /* Handle sys_sigsend, POSIX-style signal handling. */
27 register struct proc
*rp
;
28 phys_bytes src_phys
, dst_phys
;
29 struct sigcontext sc
, *scp
;
30 struct sigframe fr
, *frp
;
33 if (!isokendpt(m_ptr
->SIG_ENDPT
, &proc
)) return(EINVAL
);
34 if (iskerneln(proc
)) return(EPERM
);
37 /* Get the sigmsg structure into our address space. */
38 src_phys
= umap_local(proc_addr(PM_PROC_NR
), D
, (vir_bytes
)
39 m_ptr
->SIG_CTXT_PTR
, (vir_bytes
) sizeof(struct sigmsg
));
40 if (src_phys
== 0) return(EFAULT
);
41 phys_copy(src_phys
,vir2phys(&smsg
),(phys_bytes
) sizeof(struct sigmsg
));
43 /* Compute the user stack pointer where sigcontext will be stored. */
44 scp
= (struct sigcontext
*) smsg
.sm_stkptr
- 1;
46 /* Copy the registers to the sigcontext structure. */
47 memcpy(&sc
.sc_regs
, (char *) &rp
->p_reg
, sizeof(struct sigregs
));
49 memcpy(&sc
.sc_regs
, (char *) &rp
->p_reg
, struct(stackframe_s
));
51 memcpy(&sc
.sc_regs
, (char *) &rp
->p_reg
, sizeof(struct sigregs
));
54 /* Finish the sigcontext initialization. */
55 sc
.sc_flags
= 0; /* unused at this time */
56 sc
.sc_mask
= smsg
.sm_mask
;
58 /* Copy the sigcontext structure to the user's stack. */
59 dst_phys
= umap_local(rp
, D
, (vir_bytes
) scp
,
60 (vir_bytes
) sizeof(struct sigcontext
));
61 if (dst_phys
== 0) return(EFAULT
);
62 phys_copy(vir2phys(&sc
), dst_phys
, (phys_bytes
) sizeof(struct sigcontext
));
64 /* Initialize the sigframe structure. */
65 frp
= (struct sigframe
*) scp
- 1;
67 fr
.sf_retadr2
= (void (*)()) rp
->p_reg
.pc
;
68 fr
.sf_fp
= rp
->p_reg
.fp
;
69 rp
->p_reg
.fp
= (reg_t
) &frp
->sf_fp
;
71 fr
.sf_code
= 0; /* XXX - should be used for type of FP exception */
72 fr
.sf_signo
= smsg
.sm_signo
;
73 fr
.sf_retadr
= (void (*)()) smsg
.sm_sigreturn
;
75 /* Copy the sigframe structure to the user's stack. */
76 dst_phys
= umap_local(rp
, D
, (vir_bytes
) frp
,
77 (vir_bytes
) sizeof(struct sigframe
));
78 if (dst_phys
== 0) return(EFAULT
);
79 phys_copy(vir2phys(&fr
), dst_phys
, (phys_bytes
) sizeof(struct sigframe
));
81 #if ( _MINIX_CHIP == _CHIP_POWERPC ) /* stuff that can't be done in the assembler code. */
82 /* When the signal handlers C code is called it will write this value
83 * into the signal frame (over the sf_retadr value).
85 rp
->p_reg
.lr
= smsg
.sm_sigreturn
;
86 /* The first (and only) parameter for the user signal handler function.
88 rp
->p_reg
.retreg
= smsg
.sm_signo
; /* note the retreg == first argument */
91 /* Reset user registers to execute the signal handler. */
92 rp
->p_reg
.sp
= (reg_t
) frp
;
93 rp
->p_reg
.pc
= (reg_t
) smsg
.sm_sighandler
;
95 /* Reschedule if necessary. */
96 if(RTS_ISSET(rp
, NO_PRIORITY
))
97 RTS_LOCK_UNSET(rp
, NO_PRIORITY
);
99 kprintf("system: warning: sigsend a running process\n");
104 #endif /* USE_SIGSEND */