/*** *handler.cpp - defines C++ setHandler routine * * Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: * Defines pure MSIL C++ setHandler routine. * *******************************************************************************/ #include #include #include #include #include #include volatile __declspec(appdomain) __MPNH __mpnhHeap= (__MPNH) _encoded_null(); volatile __declspec(appdomain) _new_handler_m __nhmHeap= (_new_handler_m) _encoded_null(); /*** *int _callnewh - call the appropriate new handler * *Purpose: * Call the appropriate new handler. * *Entry: * None * *Return: * 1 for success * 0 for failure * may throw bad_alloc * *******************************************************************************/ static int __cdecl _callnewh_thunk(size_t size) { __MPNH pnh = (__MPNH) _decode_pointer(__mpnhHeap); if (pnh != NULL) { return (*pnh)(size); } else { return 0; } } static void __clrcall _callnewh_cleanup(void) { _PNH pnh=_query_new_handler(); __MPNH enull = (__MPNH) _encoded_null(); if(pnh==_callnewh_thunk && __mpnhHeap!=enull) { _set_new_handler((_PNH)NULL); } __mpnhHeap=enull; } static int __cdecl _callnewhandler_thunk ( size_t size ) { _new_handler_m pnh = (_new_handler_m) _decode_pointer(__nhmHeap); if ( pnh != NULL) { pnh(); } else { return 0; } return 1; } static void __clrcall _callnewhandler_cleanup(void) { _PNH pnh=_query_new_handler(); _new_handler_m enull = (_new_handler_m) _encoded_null(); if(pnh==_callnewhandler_thunk && __nhmHeap!=enull) { _set_new_handler((_PNH)NULL); } __nhmHeap=enull; } /*** *__MPNH _set_new_handler(__MPNH pnh) - set the new handler * *Purpose: * _set_new_handler is different from the ANSI C++ working standard definition * of set_new_handler. Therefore it has a leading underscore in its name. * *Entry: * Pointer to the new handler to be installed. * *Return: * Previous new handler * *******************************************************************************/ __MPNH _MRTIMP __cdecl _set_new_handler ( __MPNH pnh ) { if(_atexit_m_appdomain(_callnewh_cleanup)!=0) { return NULL; } __MPNH pnhOld = (__MPNH) _decode_pointer(__mpnhHeap); __mpnhHeap = (__MPNH) _encode_pointer(pnh); _set_new_handler((_PNH)_callnewh_thunk); return(pnhOld); } std::_new_handler_m _MRTIMP __cdecl std::set_new_handler ( std::_new_handler_m pnh ) throw() { if(_atexit_m_appdomain(_callnewhandler_cleanup)!=0) { return NULL; } _new_handler_m pnhOld = (_new_handler_m) _decode_pointer(__nhmHeap); __nhmHeap = (_new_handler_m) _encode_pointer(pnh); _set_new_handler((_PNH)_callnewhandler_thunk); return(pnhOld); } /*** *__MPNH __query_new_handler_m(void) - query value of new handler * *Purpose: * Obtain current new handler value. * *Entry: * None * * WARNING: This function is OBSOLETE. Use _query_new_ansi_handler instead. * *Return: * Currently installed new handler * *******************************************************************************/ __MPNH __cdecl __query_new_handler_m ( void ) { return (__MPNH) _decode_pointer(__mpnhHeap); } typedef void (__clrcall *_PHNDLR_m)(int); volatile __declspec(appdomain) static _PHNDLR_m __psignal_func[NSIG]; class __signal_init { public: __signal_init() { _PHNDLR_m enull = (_PHNDLR_m) _encoded_null(); for(int i=0; i=NSIG) { /* call signal to allow it to do error detection and handling, but without setting us up */ signal(signum, static_cast<_PHNDLR>(NULL)); return (void (__clrcall *)(int))-1; } if(_atexit_m_appdomain(_signal_cleanup)!=0) { return NULL; } _PHNDLR_m __psignal_func_old = (_PHNDLR_m) _decode_pointer(__psignal_func[signum]); __psignal_func[signum] = (_PHNDLR_m) _encode_pointer(sigact); void (__cdecl *pnative_signal_func_old)(int) = signal(signum, (void (__cdecl *)(int))__signal_thunk); if (pnative_signal_func_old == __signal_thunk) { return __psignal_func_old; } else if (pnative_signal_func_old == NULL) { return NULL; } else { return (void (__clrcall *)(int))-1; } } _MRTIMP _PHNDLR_m __cdecl signal(int signum, int sigact) { _VALIDATE_RETURN(sigact == NULL, EINVAL, NULL); return signal(signum, static_cast<_PHNDLR_m>(NULL)); }