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