📄 mhandler.cpp
字号:
/***
*handler.cpp - defines C++ setHandler routine
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* Defines pure MSIL C++ setHandler routine.
*
*******************************************************************************/
#include <internal.h>
#include <mtdll.h>
#include <new.h>
#include <signal.h>
#include <unknwn.h>
#include <minternal.h>
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) DecodePointer(__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) DecodePointer(__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) DecodePointer(__mpnhHeap);
__mpnhHeap = (__MPNH) EncodePointer(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) DecodePointer(__nhmHeap);
__nhmHeap = (_new_handler_m) EncodePointer(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) DecodePointer(__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; ++i)
{
__psignal_func[i]=enull;
}
};
};
#pragma warning(push)
#pragma warning(disable: 4074)
#pragma init_seg(compiler)
#pragma warning(pop)
static __signal_init _init;
static void __cdecl __signal_thunk(int i)
{
_PHNDLR_m local_func = (_PHNDLR_m) DecodePointer(__psignal_func[i]);
if (local_func != NULL)
{
local_func(i);
}
}
static void __clrcall _signal_cleanup(void)
{
_PHNDLR_m enull = (_PHNDLR_m) _encoded_null();
for(int i=0; i<NSIG; ++i)
{
if(__psignal_func[i]!=enull)
{
_PHNDLR _handler=signal(i, SIG_GET);
if(_handler==__signal_thunk)
{
signal(i, SIG_DFL);
}
__psignal_func[i]=enull;
}
}
}
/***
*_PHNDLR_m signal(signum, sigact) - Define a signal handler
*
*Purpose:
* The signal routine allows the user to define what action should
* be taken when various signals occur. The Win32/Dosx32 implementation
* supports seven signals, divided up into three general groups
*
* 1. Signals corresponding to OS exceptions. These are:
* SIGFPE
* SIGILL
* SIGSEGV
* Signal actions for these signals are installed by altering the
* XcptAction and SigAction fields for the appropriate entry in the
* exception-action table (XcptActTab[]).
*
* 2. Signals corresponding to ^C and ^Break. These are:
* SIGINT
* SIGBREAK
* Signal actions for these signals are installed by altering the
* _ctrlc_action and _ctrlbreak_action variables.
*
* 3. Signals which are implemented only in the runtime. That is, they
* occur only as the result of a call to raise().
* SIGABRT
* SIGTERM
*
*
*Entry:
* int signum signal type. recognized signal types are:
*
* SIGABRT (ANSI)
* SIGBREAK
* SIGFPE (ANSI)
* SIGILL (ANSI)
* SIGINT (ANSI)
* SIGSEGV (ANSI)
* SIGTERM (ANSI)
* SIGABRT_COMPAT
*
* _PHNDLR sigact signal handling function or action code. the action
* codes are:
*
* SIG_DFL - take the default action, whatever that may
* be, upon receipt of this type type of signal.
*
* SIG_DIE - *** ILLEGAL ***
* special code used in the XcptAction field of an
* XcptActTab[] entry to indicate that the runtime is
* to terminate the process upon receipt of the exception.
* not accepted as a value for sigact.
*
* SIG_IGN - ignore this type of signal
*
* [function address] - transfer control to this address
* when a signal of this type occurs.
*
*Exit:
* Good return:
* Signal returns the previous value of the signal handling function
* (e.g., SIG_DFL, SIG_IGN, etc., or [function address]). This value is
* returned in DX:AX.
*
* Error return:
* Signal returns -1 and errno is set to EINVAL. The error return is
* generally taken if the user submits bogus input values.
*
*Exceptions:
* None.
*
*******************************************************************************/
_MRTIMP _PHNDLR_m __cdecl signal(int signum, _PHNDLR_m sigact)
{
if(signum<0 || signum>=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) DecodePointer(__psignal_func[signum]);
__psignal_func[signum] = (_PHNDLR_m) EncodePointer(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 == 0, EINVAL, NULL);
return signal(signum, static_cast<_PHNDLR_m>(NULL));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -