#include "pal/signal.hpp"
#include "pal/palinternal.h"
+
+#include <errno.h>
+#include <signal.h>
+
#if !HAVE_MACH_EXCEPTIONS
#include "pal/init.h"
#include "pal/process.h"
#include "pal/virtual.h"
#include "pal/utils.h"
-#include <signal.h>
-#include <errno.h>
#include <string.h>
#include <sys/ucontext.h>
#include <sys/utsname.h>
#include "pal/context.h"
-using namespace CorUnix;
-
#ifdef SIGRTMIN
#define INJECT_ACTIVATION_SIGNAL SIGRTMIN
#endif
#if !defined(INJECT_ACTIVATION_SIGNAL) && defined(FEATURE_HIJACK)
#error FEATURE_HIJACK requires INJECT_ACTIVATION_SIGNAL to be defined
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
+
+using namespace CorUnix;
/* local type definitions *****************************************************/
#endif /* !HAVE_SIGINFO_T */
typedef void (*SIGFUNC)(int, siginfo_t *, void *);
+#if !HAVE_MACH_EXCEPTIONS
// Return context and status for the signal_handler_worker.
struct SignalHandlerWorkerReturnPoint
{
bool returnFromHandler;
CONTEXT context;
};
+#endif // !HAVE_MACH_EXCEPTIONS
/* internal function declarations *********************************************/
+static void sigterm_handler(int code, siginfo_t *siginfo, void *context);
+#if !HAVE_MACH_EXCEPTIONS
static void sigill_handler(int code, siginfo_t *siginfo, void *context);
static void sigfpe_handler(int code, siginfo_t *siginfo, void *context);
static void sigsegv_handler(int code, siginfo_t *siginfo, void *context);
static void sigbus_handler(int code, siginfo_t *siginfo, void *context);
static void sigint_handler(int code, siginfo_t *siginfo, void *context);
static void sigquit_handler(int code, siginfo_t *siginfo, void *context);
-static void sigterm_handler(int code, siginfo_t *siginfo, void *context);
static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...);
#ifdef INJECT_ACTIVATION_SIGNAL
static void inject_activation_handler(int code, siginfo_t *siginfo, void *context);
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags = 0);
static void restore_signal(int signal_id, struct sigaction *previousAction);
/* internal data declarations *********************************************/
+static bool registered_sigterm_handler = false;
+
+struct sigaction g_previous_sigterm;
+#if !HAVE_MACH_EXCEPTIONS
struct sigaction g_previous_sigill;
struct sigaction g_previous_sigtrap;
struct sigaction g_previous_sigfpe;
struct sigaction g_previous_sigsegv;
struct sigaction g_previous_sigint;
struct sigaction g_previous_sigquit;
-struct sigaction g_previous_sigterm;
-
-static bool registered_sigterm_handler = false;
#ifdef INJECT_ACTIVATION_SIGNAL
struct sigaction g_previous_activation;
// Offset of the local variable containing native context in the common_signal_handler function.
// This offset is relative to the frame pointer.
int g_common_signal_handler_context_locvar_offset = 0;
+#endif // !HAVE_MACH_EXCEPTIONS
/* public function definitions ************************************************/
+#if !HAVE_MACH_EXCEPTIONS
/*++
Function :
EnsureSignalAlternateStack
free(oss.ss_sp);
}
}
+#endif // !HAVE_MACH_EXCEPTIONS
/*++
Function :
{
TRACE("Initializing signal handlers\n");
+#if !HAVE_MACH_EXCEPTIONS
/* we call handle_signal for every possible signal, even
if we don't provide a signal handler.
{
return FALSE;
}
+#endif // !HAVE_MACH_EXCEPTIONS
if (flags & PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER)
{
registered_sigterm_handler = true;
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
#endif
issued a SIGPIPE will, instead, report an error and set errno to EPIPE.
*/
signal(SIGPIPE, SIG_IGN);
+#endif // !HAVE_MACH_EXCEPTIONS
return TRUE;
}
{
TRACE("Restoring default signal handlers\n");
+#if !HAVE_MACH_EXCEPTIONS
restore_signal(SIGILL, &g_previous_sigill);
restore_signal(SIGTRAP, &g_previous_sigtrap);
restore_signal(SIGFPE, &g_previous_sigfpe);
restore_signal(SIGSEGV, &g_previous_sigsegv);
restore_signal(SIGINT, &g_previous_sigint);
restore_signal(SIGQUIT, &g_previous_sigquit);
+#endif // !HAVE_MACH_EXCEPTIONS
if (registered_sigterm_handler)
{
restore_signal(SIGTERM, &g_previous_sigterm);
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
restore_signal(INJECT_ACTIVATION_SIGNAL, &g_previous_activation);
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
}
/* internal function definitions **********************************************/
+#if !HAVE_MACH_EXCEPTIONS
/*++
Function :
sigill_handler
restore_signal(code, &g_previous_sigquit);
kill(gPID, code);
}
+#endif // !HAVE_MACH_EXCEPTIONS
/*++
Function :
}
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
/*++
Function :
return false;
}
+#endif // !HAVE_MACH_EXCEPTIONS
/*++
Function :
errno, strerror(errno));
}
}
-
-#endif // !HAVE_MACH_EXCEPTIONS