1433d6423SLionel Sambuc #include "syslib.h"
2433d6423SLionel Sambuc #include <assert.h>
3433d6423SLionel Sambuc #include <signal.h>
4433d6423SLionel Sambuc #include <minix/sysutil.h>
5433d6423SLionel Sambuc
6433d6423SLionel Sambuc /* SEF Signal callbacks. */
7e6f5b0ccSCristiano Giuffrida static struct sef_signal_cbs {
8433d6423SLionel Sambuc sef_cb_signal_handler_t sef_cb_signal_handler;
9433d6423SLionel Sambuc sef_cb_signal_manager_t sef_cb_signal_manager;
10e6f5b0ccSCristiano Giuffrida } sef_signal_cbs = {
11433d6423SLionel Sambuc SEF_CB_SIGNAL_HANDLER_DEFAULT,
12433d6423SLionel Sambuc SEF_CB_SIGNAL_MANAGER_DEFAULT
13433d6423SLionel Sambuc };
14433d6423SLionel Sambuc
15433d6423SLionel Sambuc /* SEF Signal prototypes for sef_receive(). */
16433d6423SLionel Sambuc int do_sef_signal_request(message *m_ptr);
17433d6423SLionel Sambuc
18433d6423SLionel Sambuc /* Debug. */
19433d6423SLionel Sambuc EXTERN char* sef_debug_header(void);
20433d6423SLionel Sambuc
21433d6423SLionel Sambuc /* Information about SELF. */
22433d6423SLionel Sambuc EXTERN endpoint_t sef_self_endpoint;
23433d6423SLionel Sambuc
24433d6423SLionel Sambuc /*===========================================================================*
25433d6423SLionel Sambuc * process_sigmgr_signals *
26433d6423SLionel Sambuc *===========================================================================*/
process_sigmgr_signals(void)27433d6423SLionel Sambuc static void process_sigmgr_signals(void)
28433d6423SLionel Sambuc {
29433d6423SLionel Sambuc /* A signal manager has pending signals in the kernel. Process them. */
30433d6423SLionel Sambuc endpoint_t target;
31*7c48de6cSDavid van Moolenbroek sigset_t set;
32433d6423SLionel Sambuc int signo, r;
33433d6423SLionel Sambuc
34433d6423SLionel Sambuc while (TRUE) {
35433d6423SLionel Sambuc /* Get an arbitrary pending signal. */
36*7c48de6cSDavid van Moolenbroek if((r=sys_getksig(&target, &set)) != OK)
37433d6423SLionel Sambuc panic("SEF: sys_getksig failed: %d", r);
38433d6423SLionel Sambuc
39433d6423SLionel Sambuc if (target == NONE) {
40433d6423SLionel Sambuc /* Stop if there are no more pending signals. */
41433d6423SLionel Sambuc break;
42433d6423SLionel Sambuc } else {
43433d6423SLionel Sambuc /* Process every signal in the signal set. */
44433d6423SLionel Sambuc r = OK;
45433d6423SLionel Sambuc for (signo = SIGS_FIRST; signo <= SIGS_LAST; signo++) {
46*7c48de6cSDavid van Moolenbroek int s = sigismember(&set, signo);
47433d6423SLionel Sambuc assert(s >= 0);
48433d6423SLionel Sambuc if(s) {
49433d6423SLionel Sambuc /* Let the callback code process the signal. */
50e6f5b0ccSCristiano Giuffrida r = sef_signal_cbs.sef_cb_signal_manager(target, signo);
51433d6423SLionel Sambuc
52433d6423SLionel Sambuc /* Stop if process is gone. */
53e6f5b0ccSCristiano Giuffrida if(r == EDEADEPT) {
54433d6423SLionel Sambuc break;
55433d6423SLionel Sambuc }
56433d6423SLionel Sambuc }
57433d6423SLionel Sambuc }
58433d6423SLionel Sambuc /* Tell the kernel we are done if the target is still alive. */
59433d6423SLionel Sambuc if(r == OK) {
60433d6423SLionel Sambuc if((r=sys_endksig(target)) != OK)
61433d6423SLionel Sambuc panic("SEF: sys_endksig failed :%d", r);
62433d6423SLionel Sambuc }
63433d6423SLionel Sambuc }
64433d6423SLionel Sambuc }
65433d6423SLionel Sambuc }
66433d6423SLionel Sambuc
67433d6423SLionel Sambuc /*===========================================================================*
68433d6423SLionel Sambuc * process_sigmgr_self_signals *
69433d6423SLionel Sambuc *===========================================================================*/
process_sigmgr_self_signals(sigset_t set)70*7c48de6cSDavid van Moolenbroek static void process_sigmgr_self_signals(sigset_t set)
71433d6423SLionel Sambuc {
72433d6423SLionel Sambuc /* A signal manager has pending signals for itself. Process them. */
73433d6423SLionel Sambuc int signo;
74433d6423SLionel Sambuc
75433d6423SLionel Sambuc for (signo = SIGS_FIRST; signo <= SIGS_LAST; signo++) {
76*7c48de6cSDavid van Moolenbroek int s = sigismember(&set, signo);
77433d6423SLionel Sambuc assert(s >= 0);
78433d6423SLionel Sambuc if(s) {
79433d6423SLionel Sambuc /* Let the callback code process the signal. */
80e6f5b0ccSCristiano Giuffrida sef_signal_cbs.sef_cb_signal_handler(signo);
81433d6423SLionel Sambuc }
82433d6423SLionel Sambuc }
83433d6423SLionel Sambuc }
84433d6423SLionel Sambuc
85433d6423SLionel Sambuc /*===========================================================================*
86433d6423SLionel Sambuc * do_sef_signal_request *
87433d6423SLionel Sambuc *===========================================================================*/
do_sef_signal_request(message * m_ptr)88433d6423SLionel Sambuc int do_sef_signal_request(message *m_ptr)
89433d6423SLionel Sambuc {
90433d6423SLionel Sambuc /* Handle a SEF Signal request. */
91433d6423SLionel Sambuc int signo;
92*7c48de6cSDavid van Moolenbroek sigset_t set;
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc if(m_ptr->m_source == SYSTEM) {
95433d6423SLionel Sambuc /* Handle kernel signals. */
96*7c48de6cSDavid van Moolenbroek set = m_ptr->m_notify.sigset;
97433d6423SLionel Sambuc for (signo = SIGK_FIRST; signo <= SIGK_LAST; signo++) {
98*7c48de6cSDavid van Moolenbroek int s = sigismember(&set, signo);
99433d6423SLionel Sambuc assert(s >= 0);
100433d6423SLionel Sambuc if (s) {
101433d6423SLionel Sambuc /* Let the callback code handle the kernel signal. */
102e6f5b0ccSCristiano Giuffrida sef_signal_cbs.sef_cb_signal_handler(signo);
103433d6423SLionel Sambuc
104433d6423SLionel Sambuc /* Handle SIGKSIG for a signal manager. */
105433d6423SLionel Sambuc if(signo == SIGKSIG) {
106433d6423SLionel Sambuc process_sigmgr_signals();
107433d6423SLionel Sambuc }
108433d6423SLionel Sambuc /* Handle SIGKSIGSM for a signal manager. */
109433d6423SLionel Sambuc else if(signo == SIGKSIGSM) {
110*7c48de6cSDavid van Moolenbroek process_sigmgr_self_signals(set);
111433d6423SLionel Sambuc }
112433d6423SLionel Sambuc }
113433d6423SLionel Sambuc }
114433d6423SLionel Sambuc }
115433d6423SLionel Sambuc else {
116433d6423SLionel Sambuc /* Handle system signals from a signal manager. */
117433d6423SLionel Sambuc signo = m_ptr->m_pm_lsys_sigs_signal.num;
118433d6423SLionel Sambuc
119433d6423SLionel Sambuc /* Debug. */
120433d6423SLionel Sambuc #if SEF_SIGNAL_DEBUG
121433d6423SLionel Sambuc sef_signal_debug_begin();
122433d6423SLionel Sambuc sef_signal_dprint("%s. Got a SEF Signal request for signal %d! About to handle signal.\n",
123433d6423SLionel Sambuc sef_debug_header(), signo);
124433d6423SLionel Sambuc sef_signal_debug_end();
125433d6423SLionel Sambuc #endif
126433d6423SLionel Sambuc
127433d6423SLionel Sambuc /* Let the callback code handle the signal. */
128e6f5b0ccSCristiano Giuffrida sef_signal_cbs.sef_cb_signal_handler(signo);
129433d6423SLionel Sambuc }
130433d6423SLionel Sambuc
131433d6423SLionel Sambuc /* Return OK not to let anybody else intercept the request. */
132433d6423SLionel Sambuc return OK;
133433d6423SLionel Sambuc }
134433d6423SLionel Sambuc
135433d6423SLionel Sambuc /*===========================================================================*
136433d6423SLionel Sambuc * sef_setcb_signal_handler *
137433d6423SLionel Sambuc *===========================================================================*/
sef_setcb_signal_handler(sef_cb_signal_handler_t cb)138433d6423SLionel Sambuc void sef_setcb_signal_handler(sef_cb_signal_handler_t cb)
139433d6423SLionel Sambuc {
140433d6423SLionel Sambuc assert(cb != NULL);
141e6f5b0ccSCristiano Giuffrida sef_signal_cbs.sef_cb_signal_handler = cb;
142433d6423SLionel Sambuc }
143433d6423SLionel Sambuc
144433d6423SLionel Sambuc /*===========================================================================*
145433d6423SLionel Sambuc * sef_setcb_signal_manager *
146433d6423SLionel Sambuc *===========================================================================*/
sef_setcb_signal_manager(sef_cb_signal_manager_t cb)147433d6423SLionel Sambuc void sef_setcb_signal_manager(sef_cb_signal_manager_t cb)
148433d6423SLionel Sambuc {
149433d6423SLionel Sambuc assert(cb != NULL);
150e6f5b0ccSCristiano Giuffrida sef_signal_cbs.sef_cb_signal_manager = cb;
151433d6423SLionel Sambuc }
152433d6423SLionel Sambuc
153433d6423SLionel Sambuc /*===========================================================================*
154433d6423SLionel Sambuc * sef_cb_signal_handler_null *
155433d6423SLionel Sambuc *===========================================================================*/
sef_cb_signal_handler_null(int signo)156433d6423SLionel Sambuc void sef_cb_signal_handler_null(int signo)
157433d6423SLionel Sambuc {
158433d6423SLionel Sambuc }
159433d6423SLionel Sambuc
160433d6423SLionel Sambuc /*===========================================================================*
161433d6423SLionel Sambuc * sef_cb_signal_manager_null *
162433d6423SLionel Sambuc *===========================================================================*/
sef_cb_signal_manager_null(endpoint_t target,int signo)163433d6423SLionel Sambuc int sef_cb_signal_manager_null(endpoint_t target, int signo)
164433d6423SLionel Sambuc {
165433d6423SLionel Sambuc return OK;
166433d6423SLionel Sambuc }
167433d6423SLionel Sambuc
168433d6423SLionel Sambuc /*===========================================================================*
169433d6423SLionel Sambuc * sef_cb_signal_handler_term *
170433d6423SLionel Sambuc *===========================================================================*/
sef_cb_signal_handler_term(int signo)171433d6423SLionel Sambuc void sef_cb_signal_handler_term(int signo)
172433d6423SLionel Sambuc {
173433d6423SLionel Sambuc /* Terminate in case of SIGTERM, ignore other signals. */
174433d6423SLionel Sambuc if(signo == SIGTERM) {
175433d6423SLionel Sambuc sef_exit(1);
176433d6423SLionel Sambuc }
177433d6423SLionel Sambuc }
178433d6423SLionel Sambuc
179433d6423SLionel Sambuc /*===========================================================================*
180433d6423SLionel Sambuc * sef_cb_signal_handler_posix_default *
181433d6423SLionel Sambuc *===========================================================================*/
sef_cb_signal_handler_posix_default(int signo)182433d6423SLionel Sambuc void sef_cb_signal_handler_posix_default(int signo)
183433d6423SLionel Sambuc {
184433d6423SLionel Sambuc switch(signo) {
185433d6423SLionel Sambuc /* Ignore when possible. */
186433d6423SLionel Sambuc case SIGCHLD:
187433d6423SLionel Sambuc case SIGWINCH:
188433d6423SLionel Sambuc case SIGCONT:
189433d6423SLionel Sambuc case SIGTSTP:
190433d6423SLionel Sambuc case SIGTTIN:
191433d6423SLionel Sambuc case SIGTTOU:
192433d6423SLionel Sambuc break;
193433d6423SLionel Sambuc
194433d6423SLionel Sambuc /* Terminate in any other case unless it is a kernel signal. */
195433d6423SLionel Sambuc default:
196433d6423SLionel Sambuc if(!IS_SIGK(signo)) {
197433d6423SLionel Sambuc sef_exit(1);
198433d6423SLionel Sambuc }
199433d6423SLionel Sambuc break;
200433d6423SLionel Sambuc }
201433d6423SLionel Sambuc }
202433d6423SLionel Sambuc
203