1 /*
2 Low Level Interface Library
3
4 Copyright 1983-2008 Green Hills Software,Inc.
5
6 * This program is the property of Green Hills Software, Inc,
7 * its contents are proprietary information and no part of it
8 * is to be disclosed to anyone except employees of Green Hills
9 * Software, Inc., or as agreed in writing signed by the President
10 * of Green Hills Software, Inc.
11 */
12 /* ind_sgnl.c: ANSI signal() and raise() facilities, and NON-ANSI [u]alarm(). */
13
14 #include "indos.h"
15 #include "ind_thrd.h"
16 #include "ind_exit.h"
17 #include <cafe/os.h>
18
19 #if defined(LIBCISANSI)
20 int _U_empty_file_illegal;
21 #else /* !defined(LIBCISANSI) */
22
23 /******************************************************************************/
24 /* #include <signal.h> */
25 /* int raise(int sig); */
26 /* Raise the signal, "sig" for the current process according to ANSI C. */
27 /* If sig==SIGKILL then terminate the process with status = 1. */
28 /* Otherwise, execute the function set for the signal, "sig", by the most */
29 /* recent call to signal(), see below. */
30 /* If the function specified is SIG_IGN then do nothing. */
31 /* If the function specified is SIG_DFL then terminate the process with */
32 /* status=1. */
33 /* Otherwise set the function SIG_DFL for "sig", then execute the */
34 /* function with the signal, "sig" passed as an argument. */
35 /* Return -1 if there is no such signal. Return 0 if the operation succeeds.*/
36 /******************************************************************************/
37
38 /* BSD kill() varies slightly from Ansi raise() */
39 #if defined(ANYBSD) && !defined(NO_SIGNAL)
40 #include <signal.h>
raise(int sig)41 int raise(int sig)
42 {
43 void (*handler)() = signal(sig, SIG_IGN);
44
45 if (handler == SIG_ERR)
46 return -1;
47 if (handler == SIG_DFL) {
48 (void)signal(sig, SIG_DFL);
49 return kill(getpid(), sig);
50 }
51 if (handler != SIG_IGN)
52 (*handler)(sig);
53 return 0;
54 }
55 #elif (defined(ANYUNIX) || defined(MSW)) && !defined(NO_SIGNAL)
raise(int sig)56 int raise(int sig)
57 {
58 return(kill(getpid(),sig)); /*for a system that has a real signal()/kill()*/
59 }
60 #else /* NO_SIGNAL or ! ( BSD or ANYUNIX) */
61
62 /* this is a very basic signal mechanism, it only implements the minimal */
63 /* requirements for ANSI C */
64
65 /******************************************************************************/
66 /* #include <signal.h> */
67 /* void (*signal(int sig, void (*func)(int)))(int); */
68 /* Set the function to execute when the signal, "sig" is raised, see raise() */
69 /* above. */
70 /* If the function specified is SIG_IGN then raise() will do nothing. */
71 /* If the function specified is SIG_DFL then raise() will terminate the */
72 /* process with status=1. */
73 /* Otherwise set the function for signal "sig" to be "func". */
74 /* Return -1 if there is no such signal. Return the previous function */
75 /* specified for the signal "sig" if the operation succeeds. */
76 /* */
77 /******************************************************************************/
78 #include <signal.h>
79
80 static SignalHandler static_SignalHandlers[_SIGMAX];
81
82 static int __gh_signal_initialized;
__gh_signal_init(SignalHandler * SignalHandlers)83 static void __gh_signal_init(SignalHandler *SignalHandlers)
84 {
85 int i;
86 for (i = 1; i <= _SIGMAX; i++)
87 SignalHandlers[i-1] = SIG_DFL;
88 for (i = SIGSTOP; i <= SIGIO; i++)
89 SignalHandlers[i-1] = SIG_IGN;
90 for (i = SIGPROF; i <= SIGUSR2; i++)
91 SignalHandlers[i-1] = SIG_IGN;
92
93 /* Set __gh_signal_initialized to indicate that signal
94 handlers have been initialized. */
95 __gh_signal_initialized = 1;
96 }
97
98 #if defined(EMBEDDED)
99 /* __ghs_default_signal_handler is called for signal SIGKILL or if the
100 signal handler is SIG_DFL */
__ghs_default_signal_handler(int sig)101 void __ghs_default_signal_handler(int sig)
102 {
103 if (sig == SIGKILL) _Exit(EXIT_FAILURE);
104
105 OSPanic(__FILE__, __LINE__, "unhandled signal %d\n", sig);
106 }
107
108 #endif /* EMBEDDED */
109
signal(int sig,void (* func)(int))110 void (*signal(int sig, void (*func)(int)))(int)
111 {
112 SignalHandler temp, *handlers;
113
114 if (sig<=0 || sig>_SIGMAX)
115 return(SIG_ERR);
116 handlers = __ghs_GetThreadLocalStorageItem(__ghs_TLS_SignalHandlers);
117 if (!handlers) {
118 handlers = static_SignalHandlers;
119
120 /* Check __gh_signal_initialized. If not set,
121 initialize signal handlers. */
122 if(__gh_signal_initialized != 1) {
123 __gh_signal_init(handlers);
124 }
125 }
126
127 temp = handlers[sig-1];
128 handlers[sig-1] = func;
129 return(temp);
130 }
131
raise(int sig)132 int raise(int sig)
133 {
134 SignalHandler temp, *handlers;
135
136 if (sig<=0 || sig>_SIGMAX)
137 return(-1);
138 // handlers = __ghs_GetThreadLocalStorageItem(__ghs_TLS_SignalHandlers);
139 handlers = NULL;
140 if (!handlers) {
141 handlers = static_SignalHandlers;
142
143 /* Check __gh_signal_initialized. If not set,
144 initialize signal handlers. */
145 if(__gh_signal_initialized != 1) {
146 __gh_signal_init(handlers);
147 }
148 }
149
150 temp = handlers[sig-1];
151 if (sig==SIGKILL || temp==SIG_DFL)
152 __ghs_default_signal_handler(sig);
153 else if (temp!=SIG_IGN) {
154 handlers[sig-1] = SIG_DFL;
155 (*temp)(sig);
156 }
157 return(0);
158 }
159 #endif
160 #endif /* defined(LIBCISANSI) */
161