diff options
Diffstat (limited to 'src/pal/src/exception/console.cpp')
-rw-r--r-- | src/pal/src/exception/console.cpp | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/src/pal/src/exception/console.cpp b/src/pal/src/exception/console.cpp deleted file mode 100644 index b4b02fed1f..0000000000 --- a/src/pal/src/exception/console.cpp +++ /dev/null @@ -1,398 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -/*++ - - - -Module Name: - - console.cpp - -Abstract: - - Implementation of console ctrl API functions. - - - ---*/ - -#include "pal/thread.hpp" -#include "pal/dbgmsg.h" -#include "pal/malloc.hpp" -#include "pal/process.h" -#include <errno.h> - -using namespace CorUnix; - -SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); - -/* Constant and type definitions **********************************************/ - -typedef struct CTRL_HANDLER_LIST -{ - PHANDLER_ROUTINE handler; - struct CTRL_HANDLER_LIST *next; -} CTRL_HANDLER_LIST; - -/* Static variables ***********************************************************/ - -/* for manipulating process control-handler list, etc */ -CRITICAL_SECTION exception_critsec; - -static CTRL_HANDLER_LIST * pCtrlHandler; -static int nCtrlHandlerListLength; - -/* Internal function definitions **********************************************/ - -/*++ -Function : - SEHInitializeConsole - - Initialize stuff related to console ctrl events - - (no parameters) - -Return value : - TRUE if initialization succeeded - FALSE otherwise ---*/ -BOOL SEHInitializeConsole() -{ - pCtrlHandler = NULL; - nCtrlHandlerListLength = 0; - InternalInitializeCriticalSection(&exception_critsec); - return TRUE; -} - -/* PAL function definitions ***************************************************/ - -/*++ -Function: - SetConsoleCtrlHandler - -See MSDN doc. - ---*/ -BOOL -PALAPI -SetConsoleCtrlHandler( - IN PHANDLER_ROUTINE HandlerRoutine, - IN BOOL Add) -{ - BOOL retval = FALSE; - CTRL_HANDLER_LIST *handler; - CPalThread * pThread; - - PERF_ENTRY(SetConsoleCtrlHandler); - ENTRY("SetConsoleCtrlHandler(HandlerRoutine=%p, Add=%d)\n", - HandlerRoutine, Add); - - pThread = InternalGetCurrentThread(); - InternalEnterCriticalSection(pThread, &exception_critsec); - - if(NULL == HandlerRoutine) - { - ASSERT("HandlerRoutine may not be NULL, control-c-ignoration is not " - "supported\n"); - goto done; - } - - if(Add) - { - handler = (CTRL_HANDLER_LIST *)InternalMalloc(sizeof(CTRL_HANDLER_LIST)); - if(!handler) - { - ERROR("PAL_malloc failed! error is %d (%s)\n", errno, strerror(errno)); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto done; - } - handler->handler = HandlerRoutine; - /* From MSDN : - "handler functions are called on a last-registered, first-called - basis". So we can add the new handler at the head of the list. */ - handler->next = pCtrlHandler; - pCtrlHandler = handler; - nCtrlHandlerListLength++; - - TRACE("Adding Control Handler %p\n", HandlerRoutine); - retval = TRUE; - } - else - { - CTRL_HANDLER_LIST *temp_handler; - - handler = pCtrlHandler; - temp_handler = handler; - while(handler) - { - if(handler->handler == HandlerRoutine) - { - break; - } - temp_handler = handler; - handler = handler->next; - } - if(handler) - { - /* temp_handler it the item before the one to remove, unless it was - first in the list, in which case handler == temp_handler */ - if(handler == temp_handler) - { - /* handler to remove was first in the list... */ - nCtrlHandlerListLength--; - pCtrlHandler = handler->next; - - InternalFree(handler); - TRACE("Removing Control Handler %p from head of list\n", - HandlerRoutine ); - } - else - { - /* handler was not first in the list... */ - nCtrlHandlerListLength--; - temp_handler->next = handler->next; - InternalFree(handler); - TRACE("Removing Control Handler %p (not head of list)\n", - HandlerRoutine ); - } - retval = TRUE; - } - else - { - WARN("Trying to remove unknown Control Handler %p\n", - HandlerRoutine); - SetLastError(ERROR_INVALID_PARAMETER); - } - } -done: - InternalLeaveCriticalSection(pThread, &exception_critsec); - - LOGEXIT("SetConsoleCtrlHandler returns BOOL %d\n", retval); - PERF_EXIT(SetConsoleCtrlHandler); - return retval; -} - -#if !HAVE_MACH_EXCEPTIONS -// TODO: Implement for Mach exceptions. Not in CoreCLR surface area. -/*++ -Function: - GenerateConsoleCtrlEvent - -See MSDN doc. - -PAL specifics : - dwProcessGroupId must be zero - ---*/ -BOOL -PALAPI -GenerateConsoleCtrlEvent( - IN DWORD dwCtrlEvent, - IN DWORD dwProcessGroupId - ) -{ - int sig; - BOOL retval = FALSE; - - PERF_ENTRY(GenerateConsoleCtrlEvent); - ENTRY("GenerateConsoleCtrlEvent(dwCtrlEvent=%d, dwProcessGroupId=%#x)\n", - dwCtrlEvent, dwProcessGroupId); - - if(0!=dwProcessGroupId) - { - ASSERT("dwProcessGroupId is not 0, this is not supported by the PAL\n"); - SetLastError(ERROR_INVALID_PARAMETER); - goto done; - } - switch(dwCtrlEvent) - { - case CTRL_C_EVENT : - sig = SIGINT; - break; - case CTRL_BREAK_EVENT: - /* Map control-break on SIGQUIT */ - sig = SIGQUIT; - break; - default: - TRACE("got unknown control event\n"); - goto done; - } - - TRACE("sending signal %d to process %d\n", sig, gPID); - if(-1 == kill(gPID, sig)) - { - ASSERT("kill() failed; errno is %d (%s)\n",errno, strerror(errno)); - SetLastError(ERROR_INTERNAL_ERROR); - goto done; - } - retval = TRUE; -done: - LOGEXIT("GenerateConsoleCtrlEvent returns BOOL %d\n",retval); - PERF_EXIT(GenerateConsoleCtrlEvent); - return retval; -} -#endif // !HAVE_MACH_EXCEPTIONS - -#if !HAVE_MACH_EXCEPTIONS -// TODO: Implement for Mach exceptions. Not in CoreCLR surface area. -/*++ -Function : - SEHHandleControlEvent - - handle Control-C and Control-Break events (call handler routines, - notify debugger) - -Parameters : - DWORD event : event that occurred - LPVOID eip : instruction pointer when exception occurred - -(no return value) - -Notes : - Handlers are called on a last-installed, first called basis, until a - handler returns TRUE. If no handler returns TRUE (or no handler is - installed), the default behavior is to call the default handler of - the corresponding signal. ---*/ -void SEHHandleControlEvent(DWORD event, LPVOID eip) -{ - /* handler is actually a copy of the original list */ - CTRL_HANDLER_LIST *handler=NULL, *handlertail=NULL, *handlertmp, *newelem; - BOOL fHandled = FALSE; -#ifdef _DEBUG - BOOL fHoldingCritsec = TRUE; -#endif - - CPalThread *pthrCurrent = InternalGetCurrentThread(); - InternalEnterCriticalSection(pthrCurrent, &exception_critsec); - handlertmp = pCtrlHandler; - - /* nCtrlHandlerListLength is guaranteed to be at most 1 less than, - * and not greater than, actual length. - * We might get a stack overflow here, if the list is too large - * However, that will lead us to terminate with an error, which is - * the default behavior anyway. - */ - newelem = reinterpret_cast<CTRL_HANDLER_LIST *>( - alloca(sizeof(CTRL_HANDLER_LIST)*(nCtrlHandlerListLength+1)) - ); - - // If alloca failed, we terminate - if (newelem == NULL) { - ERROR("alloca failed!"); - InternalLeaveCriticalSection(pthrCurrent, &exception_critsec); -#ifdef _DEBUG - fHoldingCritsec = FALSE; -#endif - goto done; - } - - /* list copying */ - while(NULL!=handlertmp) - { - newelem->handler = handlertmp->handler; - newelem->next = NULL; - - /* add the new element to the list */ - if (handler == NULL) - { - handler = newelem; - } - else - { - handlertail->next = newelem; - } - handlertail = newelem; - - handlertmp = handlertmp->next; - - newelem++; - } - - // - // Once we've copied the handler list it's safe to release this - // critical section. We cannot call the user handler routines - // while holding this critsec -- a poorly written control handler - // may block indefinitely, which, in turn, would prevent graceful - // shutdown from occurring (as it would not be possible to - // suspend this thread due to its holding of an internal critical - // section). - // - // Note that this behavior is somewhat different than Windows -- - // where only a single control handler can run at a time. If we - // need to replicate that behavior we would need to enter a - // separate, non-internal critical section before calling the - // control handlers. - // - - InternalLeaveCriticalSection(pthrCurrent, &exception_critsec); -#ifdef _DEBUG - fHoldingCritsec = FALSE; -#endif - - /* second, call handler routines until one handles the event */ - - while(NULL!=handler) - { - BOOL handler_retval; - -/* reset ENTRY nesting level back to zero while inside the callback... */ -#if _ENABLE_DEBUG_MESSAGES_ - { - int old_level; - old_level = DBG_change_entrylevel(0); -#endif /* _ENABLE_DEBUG_MESSAGES_ */ - - handler_retval = handler->handler(event); - -/* ...and set nesting level back to what it was */ -#if _ENABLE_DEBUG_MESSAGES_ - DBG_change_entrylevel(old_level); - } -#endif /* _ENABLE_DEBUG_MESSAGES_ */ - - if(handler_retval) - { - TRACE("Console Control handler %p has handled event\n", - handler->handler); - fHandled = TRUE; - break; - } - handler = handler->next; - } - -done: -#ifdef _DEBUG - _ASSERT_MSG(!fHoldingCritsec, "Exiting SEHHandleControlEvent while still holding a critical section.\n"); -#endif - if(!fHandled) - { - int signalCode; - - if(CTRL_C_EVENT == event) - { - TRACE("Control-C not handled; terminating.\n"); - signalCode = SIGINT; - } - else - { - TRACE("Control-Break not handled; terminating.\n"); - signalCode = SIGQUIT; - } - - // The proper behavior for unhandled SIGINT/SIGQUIT is to set the signal handler to the default one - // and then send the SIGINT/SIGQUIT to self and let the default handler do its work. - struct sigaction action; - action.sa_handler = SIG_DFL; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(signalCode, &action, NULL); - - kill(getpid(), signalCode); - } -} - -#endif // !HAVE_MACH_EXCEPTIONS |