Stop using snprintf in write_hex_to_fd (XCC)
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.19-akaros / sysdeps / akaros / sigaction.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Copyright (c) 2015 Google Inc.
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * Kevin Klues <klueska@cs.berkeley.edu>
5  * See LICENSE for details.
6  */
7
8 #include <errno.h>
9 #include <ros/procinfo.h>
10 #include <ros/syscall.h>
11 #include <parlib/signal.h>
12 #include <parlib/vcore.h>
13 /* This is nasty.  We can't use the regular printf here.  If we do, we'll get
14  * the dreaded "multiple libcs" error during a glibc rebuild.  But we can use an
15  * akaros_printf.  If there are parts of glibc that don't link against parlib,
16  * we'll get the weak symbol.  (rtld perhaps). */
17 #include <parlib/stdio.h>
18
19 /* We define the signal_ops struct in glibc so that it is accessible without
20  * being linked to parlib. Parlib-based 2LSs will override it with their
21  * scheduler specific signal ops. */
22 struct signal_ops *signal_ops;
23
24 /* This is list of sigactions associated with each posix signal. */
25 static struct sigaction sigactions[_NSIG];
26
27 /* These are the default handlers for each posix signal.  They are listed in
28  * SIGNAL(7) of the Linux Programmer's Manual.  We run them as default
29  * sigactions, instead of the older handlers, so that we have access to the
30  * faulting context.
31  *
32  * Exit codes are set as suggested in the following link.  I wish I could find
33  * the definitive source, but this will have to do for now.
34  * http://unix.stackexchange.com/questions/99112/default-exit-code-when-process-is-terminated
35  * */
36 static void default_term_handler(int signr, siginfo_t *info, void *ctx)
37 {
38         ros_syscall(SYS_proc_destroy, __procinfo.pid, signr, 0, 0, 0, 0);
39 }
40
41 static void default_core_handler(int signr, siginfo_t *info, void *ctx)
42 {
43         akaros_printf("Segmentation Fault on PID %d (sorry, no core dump yet)\n",
44                       __procinfo.pid);
45         if (ctx)
46                 print_user_context((struct user_context*)ctx);
47         else
48                 akaros_printf("No ctx for %s\n", __func__);
49         if (info) {
50                 /* ghetto, we don't have access to the PF err, since we only have a few
51                  * fields available in siginfo (e.g. there's no si_trapno). */
52                 akaros_printf("Fault type %d at addr %p\n", info->si_errno,
53                               info->si_addr);
54         } else {
55                 akaros_printf("No fault info\n");
56         }
57         default_term_handler((1 << 7) + signr, info, ctx);
58 }
59
60 static void default_stop_handler(int signr, siginfo_t *info, void *ctx)
61 {
62         akaros_printf("Stop signal received!  No support to stop yet though!\n");
63 }
64
65 static void default_cont_handler(int signr, siginfo_t *info, void *ctx)
66 {
67         akaros_printf("Cont signal received!  No support to cont yet though!\n");
68 }
69
70 typedef void (*__sigacthandler_t)(int, siginfo_t *, void *);
71 #define SIGACT_ERR      ((__sigacthandler_t) -1)        /* Error return.  */
72 #define SIGACT_DFL      ((__sigacthandler_t) 0)         /* Default action.  */
73 #define SIGACT_IGN      ((__sigacthandler_t) 1)         /* Ignore signal.  */
74
75 static __sigacthandler_t default_handlers[] = {
76         [SIGHUP]    = default_term_handler,
77         [SIGINT]    = default_term_handler,
78         [SIGQUIT]   = default_core_handler,
79         [SIGILL]    = default_core_handler,
80         [SIGTRAP]   = default_core_handler,
81         [SIGABRT]   = default_core_handler,
82         [SIGIOT]    = default_core_handler,
83         [SIGBUS]    = default_core_handler,
84         [SIGFPE]    = default_core_handler,
85         [SIGKILL]   = default_term_handler,
86         [SIGUSR1]   = default_term_handler,
87         [SIGSEGV]   = default_core_handler,
88         [SIGUSR2]   = default_term_handler,
89         [SIGPIPE]   = default_term_handler,
90         [SIGALRM]   = default_term_handler,
91         [SIGTERM]   = default_term_handler,
92         [SIGSTKFLT] = default_term_handler,
93         [SIGCHLD]   = SIGACT_IGN,
94         [SIGCONT]   = default_cont_handler,
95         [SIGSTOP]   = default_stop_handler,
96         [SIGTSTP]   = default_stop_handler,
97         [SIGTTIN]   = default_stop_handler,
98         [SIGTTOU]   = default_stop_handler,
99         [SIGURG]    = default_term_handler,
100         [SIGXCPU]   = SIGACT_IGN,
101         [SIGXFSZ]   = default_core_handler,
102         [SIGVTALRM] = default_term_handler,
103         [SIGPROF]   = default_term_handler,
104         [SIGWINCH]  = SIGACT_IGN,
105         [SIGIO]     = default_term_handler,
106         [SIGPWR]    = SIGACT_IGN,
107         [SIGSYS]    = default_core_handler,
108         [SIGSYS+1 ... _NSIG-1] = SIGACT_IGN
109 };
110
111 /* This is the akaros posix signal trigger.  Signals are dispatched from
112  * this function to their proper posix signal handler */
113 void trigger_posix_signal(int sig_nr, struct siginfo *info, void *aux)
114 {
115         struct sigaction *action;
116
117         if (sig_nr >= _NSIG || sig_nr < 0)
118                 return;
119         action = &sigactions[sig_nr];
120         /* Would like a switch/case here, but they are pointers.  We can also get
121          * away with this check early since sa_handler and sa_sigaction are macros
122          * referencing the same union.  The man page isn't specific about whether or
123          * not you need to care about SA_SIGINFO when sending DFL/ERR/IGN. */
124         if (action->sa_handler == SIG_ERR)
125                 return;
126         if (action->sa_handler == SIG_IGN)
127                 return;
128         if (action->sa_handler == SIG_DFL) {
129                 if (default_handlers[sig_nr] != SIGACT_IGN)
130                         default_handlers[sig_nr](sig_nr, info, aux);
131                 return;
132         }
133
134         if (action->sa_flags & SA_SIGINFO) {
135                 /* If NULL info struct passed in, construct our own */
136                 struct siginfo s = {0};
137
138                 if (info == NULL)
139                         info = &s;
140                 /* Make sure the caller either already set singo in the info struct, or
141                  * if they didn't, make sure it has been zeroed out (i.e. not just some
142                  * garbage on the stack. */
143                 assert(info->si_signo == sig_nr || info->si_signo == 0);
144                 info->si_signo = sig_nr;
145                 /* TODO: consider info->pid and whatnot */
146                 /* We assume that this function follows the proper calling convention
147                  * (i.e. it wasn't written in some crazy assembly function that
148                  * trashes all its registers, i.e GO's default runtime handler) */
149                 action->sa_sigaction(sig_nr, info, aux);
150         } else {
151                 action->sa_handler(sig_nr);
152         }
153 }
154
155 int __sigaction(int __sig, __const struct sigaction *__restrict __act,
156                 struct sigaction *__restrict __oact)
157 {
158         if (__sig <= 0 || __sig >= NSIG) {
159                 __set_errno(EINVAL);
160                 return -1;
161         }
162         if (__oact)
163                 *__oact = sigactions[__sig];
164         if (!__act)
165                 return 0;
166         sigactions[__sig] = *__act;
167         return 0;
168 }
169 libc_hidden_def(__sigaction)
170 weak_alias(__sigaction, sigaction)