Default signal handlers are sigactions
[akaros.git] / user / parlib / signal.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Kevin Klues <klueska@cs.berkeley.edu>
4  * See LICENSE for details.
5  *
6  * POSIX signal handling glue.  All glibc programs link against parlib, so they
7  * will get this mixed in.  Mostly just registration of signal handlers.
8  *
9  * POSIX signal handling caveats:
10  *      - We don't copy signal handling tables or anything across forks or execs
11  *      - We don't send meaningful info in the siginfos, nor do we pass pid/uids on
12  *      signals coming from a kill.  This is especially pertinent for sigqueue,
13  *      which needs a payload (value) and sending PID
14  *      - We run handlers in vcore context, so any blocking syscall will spin.
15  *      Regular signals have restrictions on their syscalls too, though not this
16  *      great.  We could spawn off a uthread to run the handler, given that we have
17  *      a 2LS (which we don't for SCPs).
18  *      - We don't do anything with signal blocking/masking.  When in a signal
19  *      handler, you won't get interrupted with another signal handler (so long as
20  *      you run it in vcore context!).  With uthreads, you could get interrupted.
21  *      There is also no process wide signal blocking yet (sigprocmask()).  If this
22  *      is desired, we can abort certain signals when we h_p_signal(), 
23  *      - Likewise, we don't do waiting for particular signals yet.  Just about the
24  *      only thing we do is allow the registration of signal handlers. 
25  *      - Check each function for further notes.  */
26
27 #include <signal.h>
28 #include <stdio.h>
29
30 #include <event.h>
31 #include <errno.h>
32 #include <assert.h>
33 #include <ros/procinfo.h>
34 #include <ros/syscall.h>
35 #include <vcore.h> /* for print_user_context() */
36
37 /* This is list of sigactions associated with each posix signal. */
38 static struct sigaction sigactions[_NSIG - 1];
39
40 /* These are the default handlers for each posix signal.  They are listed in
41  * SIGNAL(7) of the Linux Programmer's Manual.  We run them as default
42  * sigactions, instead of the older handlers, so that we have access to the
43  * faulting context.
44  *
45  * Exit codes are set as suggested in the following link.  I wish I could find
46  * the definitive source, but this will have to do for now.
47  * http://unix.stackexchange.com/questions/99112/default-exit-code-when-process-is-terminated
48  * */
49 static void default_term_handler(int signr, siginfo_t *info, void *ctx)
50 {
51         ros_syscall(SYS_proc_destroy, __procinfo.pid, signr, 0, 0, 0, 0);
52 }
53
54 static void default_core_handler(int signr, siginfo_t *info, void *ctx)
55 {
56         fprintf(stderr, "Segmentation Fault (sorry, no core dump yet)\n");
57         print_user_context((struct user_context*)ctx);
58         if (info) {
59                 /* ghetto, we don't have access to the PF err, since we only have a few
60                  * fields available in siginfo (e.g. there's no si_trapno). */
61                 fprintf(stderr, "Fault type %d at addr %p\n", info->si_errno,
62                         info->si_addr);
63         } else {
64                 fprintf(stderr, "No fault info\n");
65         }
66         default_term_handler((1 << 7) + signr, info, ctx);
67 }
68
69 static void default_stop_handler(int signr, siginfo_t *info, void *ctx)
70 {
71         fprintf(stderr, "Stop signal received!  No support to stop yet though!\n");
72 }
73
74 static void default_cont_handler(int signr, siginfo_t *info, void *ctx)
75 {
76         fprintf(stderr, "Cont signal received!  No support to cont yet though!\n");
77 }
78
79 typedef void (*__sigacthandler_t)(int, siginfo_t *, void *);
80 #define SIGACT_ERR      ((__sigacthandler_t) -1)        /* Error return.  */
81 #define SIGACT_DFL      ((__sigacthandler_t) 0)         /* Default action.  */
82 #define SIGACT_IGN      ((__sigacthandler_t) 1)         /* Ignore signal.  */
83
84 static __sigacthandler_t default_handlers[] = {
85         [SIGHUP]    = default_term_handler, 
86         [SIGINT]    = default_term_handler, 
87         [SIGQUIT]   = default_core_handler, 
88         [SIGILL]    = default_core_handler, 
89         [SIGTRAP]   = default_core_handler, 
90         [SIGABRT]   = default_core_handler, 
91         [SIGIOT]    = default_core_handler, 
92         [SIGBUS]    = default_core_handler, 
93         [SIGFPE]    = default_core_handler, 
94         [SIGKILL]   = default_term_handler, 
95         [SIGUSR1]   = default_term_handler, 
96         [SIGSEGV]   = default_core_handler, 
97         [SIGUSR2]   = default_term_handler, 
98         [SIGPIPE]   = default_term_handler, 
99         [SIGALRM]   = default_term_handler, 
100         [SIGTERM]   = default_term_handler, 
101         [SIGSTKFLT] = default_term_handler, 
102         [SIGCHLD]   = SIGACT_IGN,
103         [SIGCONT]   = default_cont_handler, 
104         [SIGSTOP]   = default_stop_handler, 
105         [SIGTSTP]   = default_stop_handler, 
106         [SIGTTIN]   = default_stop_handler, 
107         [SIGTTOU]   = default_stop_handler, 
108         [SIGURG]    = default_term_handler, 
109         [SIGXCPU]   = SIGACT_IGN,
110         [SIGXFSZ]   = default_core_handler, 
111         [SIGVTALRM] = default_term_handler, 
112         [SIGPROF]   = default_term_handler, 
113         [SIGWINCH]  = SIGACT_IGN,
114         [SIGIO]     = default_term_handler, 
115         [SIGPWR]    = SIGACT_IGN,
116         [SIGSYS]    = default_core_handler
117 };
118
119
120 /* This is the akaros posix signal trigger.  Signals are dispatched from
121  * this function to their proper posix signal handler */
122 void trigger_posix_signal(int sig_nr, struct siginfo *info, void *aux)
123 {
124         struct sigaction *action;
125         if (sig_nr > _NSIG - 1 || sig_nr < 0)
126                 return;
127         action = &sigactions[sig_nr];
128         /* Would like a switch/case here, but they are pointers.  We can also get
129          * away with this check early since sa_handler and sa_sigaction are macros
130          * referencing the same union.  The man page isn't specific about whether or
131          * not you need to care about SA_SIGINFO when sending DFL/ERR/IGN. */
132         if (action->sa_handler == SIG_ERR)
133                 return;
134         if (action->sa_handler == SIG_IGN)
135                 return;
136         if (action->sa_handler == SIG_DFL) {
137                 if (default_handlers[sig_nr] != SIGACT_IGN)
138                         default_handlers[sig_nr](sig_nr, info, aux);
139                 return;
140         }
141
142         if (action->sa_flags & SA_SIGINFO) {
143                 /* If NULL info struct passed in, construct our own */
144                 struct siginfo s = {0};
145                 if (info == NULL)
146                         info = &s;
147                 /* Make sure the caller either already set singo in the info struct, or
148                  * if they didn't, make sure it has been zeroed out (i.e. not just some
149                  * garbage on the stack. */
150                 assert(info->si_signo == sig_nr || info->si_signo == 0);
151                 info->si_signo = sig_nr;
152                 /* TODO: consider info->pid and whatnot */
153                 /* We assume that this function follows the proper calling convention
154                  * (i.e. it wasn't written in some crazy assembly function that
155                  * trashes all its registers, i.e GO's default runtime handler) */
156                 action->sa_sigaction(sig_nr, info, aux);
157         } else {
158                 action->sa_handler(sig_nr);
159         }
160 }
161
162 /* This is the catch all akaros event->posix signal handler.  All posix signals
163  * are received in a single akaros event type.  They are then dispatched from
164  * this function to their proper posix signal handler */
165 static void handle_event(struct event_msg *ev_msg, unsigned int ev_type,
166                          void *data)
167 {
168         int sig_nr;
169         struct siginfo info = {0};
170         info.si_code = SI_USER;
171
172         assert(ev_msg);
173         sig_nr = ev_msg->ev_arg1;
174         trigger_posix_signal(sig_nr, &info, 0);
175 }
176
177 /* Called from uthread_slim_init() */
178 void init_posix_signals(void)
179 {
180         struct event_queue *posix_sig_ev_q;
181         register_ev_handler(EV_POSIX_SIGNAL, handle_event, 0);
182         posix_sig_ev_q = get_big_event_q();
183         assert(posix_sig_ev_q);
184         posix_sig_ev_q->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_FALLBACK;
185         register_kevent_q(posix_sig_ev_q, EV_POSIX_SIGNAL);
186 }
187
188 int sigaddset(sigset_t *__set, int __signo)
189 {
190         if (__signo == 0 || __signo > _NSIG) {
191                 errno = EINVAL;
192                 return -1;
193         }
194         __sigaddset(__set, __signo);
195         return 0;
196 }
197
198 int sigdelset(sigset_t *__set, int __signo)
199 {
200         if (__signo == 0 || __signo > _NSIG) {
201                 errno = EINVAL;
202                 return -1;
203         }
204         __sigdelset(__set, __signo);
205         return 0;
206 }
207
208 int sigismember(__const sigset_t *__set, int __signo)
209 {
210         if (__signo == 0 || __signo > _NSIG) {
211                 errno = EINVAL;
212                 return -1;
213         }
214         __sigismember(__set, __signo);
215         return 0;
216 }
217
218 /* Would need a layer/interposition to ignore blocked signals when they come in,
219  * and then to manually play them when they are unblocked, like how x86 does
220  * with the IRR and the ISR for interrupt delivery. */
221 int sigprocmask(int __how, __const sigset_t *__restrict __set,
222                 sigset_t *__restrict __oset)
223 {
224         printf("Function not supported generically! "
225            "Use 2LS specific function e.g. pthread_sigmask\n");
226         return 0;
227 }
228
229 /* Could do this with a loop on delivery of the signal, sleeping and getting
230  * woken up by the kernel on any event, like we do with async syscalls. */
231 int sigsuspend(__const sigset_t *__set)
232 {
233         return 0;
234 }
235
236 int sigaction(int __sig, __const struct sigaction *__restrict __act,
237               struct sigaction *__restrict __oact)
238 {
239         if (__sig > _NSIG - 1 || __sig < 0)
240                 return -1;
241         if (__oact) {
242                 *__oact = sigactions[__sig];
243         }
244         if (!__act)
245                 return 0;
246         sigactions[__sig] = *__act;
247         return 0;
248 }
249
250 /* Not really possible or relevant - you'd need to walk/examine the event UCQ */
251 int sigpending(sigset_t *__set)
252 {
253         return 0;
254 }
255
256 /* Can be done similar to sigsuspend */
257 int sigwait(__const sigset_t *__restrict __set, int *__restrict __sig)
258 {
259         return 0;
260 }
261
262 /* Can be done similar to sigsuspend */
263 int sigwaitinfo(__const sigset_t *__restrict __set,
264                 siginfo_t *__restrict __info)
265 {
266         return 0;
267 }
268
269 /* Can be done similar to sigsuspend, with an extra alarm syscall */
270 int sigtimedwait(__const sigset_t *__restrict __set,
271                  siginfo_t *__restrict __info,
272                  __const struct timespec *__restrict __timeout)
273 {
274         return 0;
275 }
276
277 /* Needs support with trigger_posix_signal to deal with passing values with POSIX
278  * signals. */
279 int sigqueue(__pid_t __pid, int __sig, __const union sigval __val)
280 {
281         return 0;
282 }
283
284 /* Old BSD interface, deprecated */
285 int sigvec(int __sig, __const struct sigvec *__vec, struct sigvec *__ovec)
286 {
287         return 0;
288 }
289
290 /* Linux specific, and not really needed for us */
291 int sigreturn(struct sigcontext *__scp)
292 {
293         return 0;
294 }
295
296 /* Akaros can't have signals interrupt syscalls to need a restart, though we can
297  * re-wake-up the process while it is waiting for its syscall. */
298 int siginterrupt(int __sig, int __interrupt)
299 {
300         return 0;
301 }
302
303 /* This is managed by vcore / 2LS code */
304 int sigstack(struct sigstack *__ss, struct sigstack *__oss)
305 {
306         return 0;
307 }
308
309 /* This is managed by vcore / 2LS code */
310 int sigaltstack(__const struct sigaltstack *__restrict __ss,
311                 struct sigaltstack *__restrict __oss)
312 {
313         return 0;
314 }
315
316 __sighandler_t signal(int sig, __sighandler_t handler)
317 {
318         int ret;
319         struct sigaction newsa = {0};
320         struct sigaction oldsa = {0};
321         newsa.sa_handler = handler;
322         ret = sigaction(sig, &newsa, &oldsa);
323         if (ret < 0) {
324                 errno = EINVAL;
325                 return SIG_ERR;
326         }
327         return oldsa.sa_handler;
328 }