__aeabi_ldivmod: fix sign logic
[minix.git] / lib / libsys / sef_signal.c
blob8136c21d6fbdb8510bc1a8920d7abab8423c4605
1 #include "syslib.h"
2 #include <assert.h>
3 #include <signal.h>
4 #include <minix/sysutil.h>
6 /* SEF Signal callbacks. */
7 static struct sef_cbs {
8 sef_cb_signal_handler_t sef_cb_signal_handler;
9 sef_cb_signal_manager_t sef_cb_signal_manager;
10 } sef_cbs = {
11 SEF_CB_SIGNAL_HANDLER_DEFAULT,
12 SEF_CB_SIGNAL_MANAGER_DEFAULT
15 /* SEF Signal prototypes for sef_receive(). */
16 int do_sef_signal_request(message *m_ptr);
18 /* Debug. */
19 EXTERN char* sef_debug_header(void);
21 /* Information about SELF. */
22 EXTERN endpoint_t sef_self_endpoint;
24 /*===========================================================================*
25 * process_sigmgr_signals *
26 *===========================================================================*/
27 static void process_sigmgr_signals(void)
29 /* A signal manager has pending signals in the kernel. Process them. */
30 endpoint_t target;
31 sigset_t sigset;
32 int signo, r;
34 while (TRUE) {
35 /* Get an arbitrary pending signal. */
36 if((r=sys_getksig(&target, &sigset)) != OK)
37 panic("SEF: sys_getksig failed: %d", r);
39 if (target == NONE) {
40 /* Stop if there are no more pending signals. */
41 break;
42 } else {
43 /* Process every signal in the signal set. */
44 r = OK;
45 for (signo = SIGS_FIRST; signo <= SIGS_LAST; signo++) {
46 if(sigismember(&sigset, signo)) {
47 /* Let the callback code process the signal. */
48 r = sef_cbs.sef_cb_signal_manager(target, signo);
50 /* Stop if process is gone. */
51 if(r == EDEADSRCDST) {
52 break;
56 /* Tell the kernel we are done if the target is still alive. */
57 if(r == OK) {
58 if((r=sys_endksig(target)) != OK)
59 panic("SEF: sys_endksig failed :%d", r);
65 /*===========================================================================*
66 * process_sigmgr_self_signals *
67 *===========================================================================*/
68 static void process_sigmgr_self_signals(sigset_t sigset)
70 /* A signal manager has pending signals for itself. Process them. */
71 int signo;
73 for (signo = SIGS_FIRST; signo <= SIGS_LAST; signo++) {
74 if(sigismember(&sigset, signo)) {
75 /* Let the callback code process the signal. */
76 sef_cbs.sef_cb_signal_handler(signo);
81 /*===========================================================================*
82 * do_sef_signal_request *
83 *===========================================================================*/
84 int do_sef_signal_request(message *m_ptr)
86 /* Handle a SEF Signal request. */
87 int signo;
88 sigset_t sigset;
90 if(m_ptr->m_source == SYSTEM) {
91 /* Handle kernel signals. */
92 sigset = m_ptr->NOTIFY_ARG;
93 for (signo = SIGK_FIRST; signo <= SIGK_LAST; signo++) {
94 if (sigismember(&sigset, signo)) {
95 /* Let the callback code handle the kernel signal. */
96 sef_cbs.sef_cb_signal_handler(signo);
98 /* Handle SIGKSIG for a signal manager. */
99 if(signo == SIGKSIG) {
100 process_sigmgr_signals();
102 /* Handle SIGKSIGSM for a signal manager. */
103 else if(signo == SIGKSIGSM) {
104 process_sigmgr_self_signals(sigset);
109 else {
110 /* Handle system signals from a signal manager. */
111 signo = m_ptr->SIGS_SIG_NUM;
113 /* Debug. */
114 #if SEF_SIGNAL_DEBUG
115 sef_signal_debug_begin();
116 sef_signal_dprint("%s. Got a SEF Signal request for signal %d! About to handle signal.\n",
117 sef_debug_header(), signo);
118 sef_signal_debug_end();
119 #endif
121 /* Let the callback code handle the signal. */
122 sef_cbs.sef_cb_signal_handler(signo);
125 /* Return OK not to let anybody else intercept the request. */
126 return OK;
129 /*===========================================================================*
130 * sef_setcb_signal_handler *
131 *===========================================================================*/
132 void sef_setcb_signal_handler(sef_cb_signal_handler_t cb)
134 assert(cb != NULL);
135 sef_cbs.sef_cb_signal_handler = cb;
138 /*===========================================================================*
139 * sef_setcb_signal_manager *
140 *===========================================================================*/
141 void sef_setcb_signal_manager(sef_cb_signal_manager_t cb)
143 assert(cb != NULL);
144 sef_cbs.sef_cb_signal_manager = cb;
147 /*===========================================================================*
148 * sef_cb_signal_handler_null *
149 *===========================================================================*/
150 void sef_cb_signal_handler_null(int signo)
154 /*===========================================================================*
155 * sef_cb_signal_manager_null *
156 *===========================================================================*/
157 int sef_cb_signal_manager_null(endpoint_t target, int signo)
159 return OK;
162 /*===========================================================================*
163 * sef_cb_signal_handler_term *
164 *===========================================================================*/
165 void sef_cb_signal_handler_term(int signo)
167 /* Terminate in case of SIGTERM, ignore other signals. */
168 if(signo == SIGTERM) {
169 sef_exit(1);
173 /*===========================================================================*
174 * sef_cb_signal_handler_posix_default *
175 *===========================================================================*/
176 void sef_cb_signal_handler_posix_default(int signo)
178 switch(signo) {
179 /* Ignore when possible. */
180 case SIGCHLD:
181 case SIGWINCH:
182 case SIGCONT:
183 case SIGTSTP:
184 case SIGTTIN:
185 case SIGTTOU:
186 break;
188 /* Terminate in any other case unless it is a kernel signal. */
189 default:
190 if(!IS_SIGK(signo)) {
191 sef_exit(1);
193 break;