/* Low Level Interface Library Copyright 1983-2008 Green Hills Software,Inc. * This program is the property of Green Hills Software, Inc, * its contents are proprietary information and no part of it * is to be disclosed to anyone except employees of Green Hills * Software, Inc., or as agreed in writing signed by the President * of Green Hills Software, Inc. */ /* ind_sgnl.c: ANSI signal() and raise() facilities, and NON-ANSI [u]alarm(). */ #include "indos.h" #include "ind_thrd.h" #include "ind_exit.h" #include #if defined(LIBCISANSI) int _U_empty_file_illegal; #else /* !defined(LIBCISANSI) */ /******************************************************************************/ /* #include */ /* int raise(int sig); */ /* Raise the signal, "sig" for the current process according to ANSI C. */ /* If sig==SIGKILL then terminate the process with status = 1. */ /* Otherwise, execute the function set for the signal, "sig", by the most */ /* recent call to signal(), see below. */ /* If the function specified is SIG_IGN then do nothing. */ /* If the function specified is SIG_DFL then terminate the process with */ /* status=1. */ /* Otherwise set the function SIG_DFL for "sig", then execute the */ /* function with the signal, "sig" passed as an argument. */ /* Return -1 if there is no such signal. Return 0 if the operation succeeds.*/ /******************************************************************************/ /* BSD kill() varies slightly from Ansi raise() */ #if defined(ANYBSD) && !defined(NO_SIGNAL) #include int raise(int sig) { void (*handler)() = signal(sig, SIG_IGN); if (handler == SIG_ERR) return -1; if (handler == SIG_DFL) { (void)signal(sig, SIG_DFL); return kill(getpid(), sig); } if (handler != SIG_IGN) (*handler)(sig); return 0; } #elif (defined(ANYUNIX) || defined(MSW)) && !defined(NO_SIGNAL) int raise(int sig) { return(kill(getpid(),sig)); /*for a system that has a real signal()/kill()*/ } #else /* NO_SIGNAL or ! ( BSD or ANYUNIX) */ /* this is a very basic signal mechanism, it only implements the minimal */ /* requirements for ANSI C */ /******************************************************************************/ /* #include */ /* void (*signal(int sig, void (*func)(int)))(int); */ /* Set the function to execute when the signal, "sig" is raised, see raise() */ /* above. */ /* If the function specified is SIG_IGN then raise() will do nothing. */ /* If the function specified is SIG_DFL then raise() will terminate the */ /* process with status=1. */ /* Otherwise set the function for signal "sig" to be "func". */ /* Return -1 if there is no such signal. Return the previous function */ /* specified for the signal "sig" if the operation succeeds. */ /* */ /******************************************************************************/ #include static SignalHandler static_SignalHandlers[_SIGMAX]; static int __gh_signal_initialized; static void __gh_signal_init(SignalHandler *SignalHandlers) { int i; for (i = 1; i <= _SIGMAX; i++) SignalHandlers[i-1] = SIG_DFL; for (i = SIGSTOP; i <= SIGIO; i++) SignalHandlers[i-1] = SIG_IGN; for (i = SIGPROF; i <= SIGUSR2; i++) SignalHandlers[i-1] = SIG_IGN; /* Set __gh_signal_initialized to indicate that signal handlers have been initialized. */ __gh_signal_initialized = 1; } #if defined(EMBEDDED) /* __ghs_default_signal_handler is called for signal SIGKILL or if the signal handler is SIG_DFL */ void __ghs_default_signal_handler(int sig) { if (sig == SIGKILL) _Exit(EXIT_FAILURE); OSPanic(__FILE__, __LINE__, "unhandled signal %d\n", sig); } #endif /* EMBEDDED */ void (*signal(int sig, void (*func)(int)))(int) { SignalHandler temp, *handlers; if (sig<=0 || sig>_SIGMAX) return(SIG_ERR); handlers = __ghs_GetThreadLocalStorageItem(__ghs_TLS_SignalHandlers); if (!handlers) { handlers = static_SignalHandlers; /* Check __gh_signal_initialized. If not set, initialize signal handlers. */ if(__gh_signal_initialized != 1) { __gh_signal_init(handlers); } } temp = handlers[sig-1]; handlers[sig-1] = func; return(temp); } int raise(int sig) { SignalHandler temp, *handlers; if (sig<=0 || sig>_SIGMAX) return(-1); // handlers = __ghs_GetThreadLocalStorageItem(__ghs_TLS_SignalHandlers); handlers = NULL; if (!handlers) { handlers = static_SignalHandlers; /* Check __gh_signal_initialized. If not set, initialize signal handlers. */ if(__gh_signal_initialized != 1) { __gh_signal_init(handlers); } } temp = handlers[sig-1]; if (sig==SIGKILL || temp==SIG_DFL) __ghs_default_signal_handler(sig); else if (temp!=SIG_IGN) { handlers[sig-1] = SIG_DFL; (*temp)(sig); } return(0); } #endif #endif /* defined(LIBCISANSI) */