xref: /minix3/minix/lib/libsys/sef_signal.c (revision 7c48de6cc4c6d56f2277d378dba01dbac8a8c3b9)
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