📄 winsig.c
字号:
* look up the proper entry in the exception-action table. note that
* if several exceptions are mapped to the same signal, this returns
* the pointer to first such entry in the exception action table. it
* is assumed that the other entries immediately follow this one.
*/
if ( (pxcptact = siglookup(signum, ptd->_pxcptacttab)) == NULL )
goto sigreterror;
/*
* SIGSEGV, SIGILL and SIGFPE all have more than one exception mapped
* to them. the code below depends on the exceptions corresponding to
* the same signal being grouped together in the exception-action
* table.
*/
/*
* store old signal action code for return value
*/
oldsigact = pxcptact->XcptAction;
if(sigact!=SIG_GET)
{
/*
* loop through all entries corresponding to the
* given signal and update the SigAction and XcptAction
* fields as appropriate
*/
while ( pxcptact->SigNum == signum ) {
/*
* take care of the SIG_IGN and SIG_DFL action
* codes
*/
pxcptact->XcptAction = sigact;
/*
* make sure we don't run off the end of the table
*/
if ( ++pxcptact >= ((struct _XCPT_ACTION *)(ptd->_pxcptacttab)
+ _XcptActTabCount) )
break;
}
}
sigretok:
return(oldsigact);
sigreterror:
switch(signum)
{
case _SIGHUP_IGNORE:
case _SIGQUIT_IGNORE:
case _SIGPIPE_IGNORE:
case _SIGIOINT_IGNORE:
case _SIGSTOP_IGNORE:
return SIG_ERR;
default:
_VALIDATE_RETURN(("Invalid signal or error", 0), EINVAL, SIG_ERR);
/* should never happen, but compiler can't tell */
return SIG_ERR;
}
}
/***
*int raise(signum) - Raise a signal
*
*Purpose:
* This routine raises a signal (i.e., performs the action currently
* defined for this signal). The action associated with the signal is
* evoked directly without going through intermediate dispatching or
* handling.
*
*Entry:
* int signum - signal type (e.g., SIGINT)
*
*Exit:
* returns 0 on good return, -1 on bad return.
*
*Exceptions:
* May not return. Raise has no control over the action
* routines defined for the various signals. Those routines may
* abort, terminate, etc. In particular, the default actions for
* certain signals will terminate the program.
*
*******************************************************************************/
int __cdecl raise (
int signum
)
{
_PHNDLR sigact;
_PHNDLR *psigact;
PEXCEPTION_POINTERS oldpxcptinfoptrs;
int oldfpecode;
int indx;
int siglock = 0;
_ptiddata ptd=NULL;
switch (signum) {
case SIGINT:
sigact = *(psigact = &ctrlc_action);
siglock++;
break;
case SIGBREAK:
sigact = *(psigact = &ctrlbreak_action);
siglock++;
break;
case SIGABRT:
case SIGABRT_COMPAT:
sigact = *(psigact = &abort_action);
siglock++;
break;
case SIGTERM:
sigact = *(psigact = &term_action);
siglock++;
break;
case SIGFPE:
case SIGILL:
case SIGSEGV:
ptd = _getptd_noexit();
if (!ptd)
return (-1);
sigact = *(psigact = &(siglookup( signum,
ptd->_pxcptacttab )->XcptAction));
goto decode_done;
break;
default:
/*
* unsupported signal, return an error
*/
_VALIDATE_RETURN(("Invalid signal or error", 0), EINVAL, -1);
}
sigact = (_PHNDLR) DecodePointer(sigact);
decode_done:
/*
* If the current action is SIG_IGN, just return
*/
if ( sigact == SIG_IGN )
return(0);
/*
* If the current action is SIG_DFL, take the default action
*/
if ( sigact == SIG_DFL ) {
/*
* The current default action for all of the supported
* signals is to terminate with an exit code of 3.
*/
_exit(3);
}
/*
* if signum is one of the 'process-wide' signals (i.e., SIGINT,
* SIGBREAK, SIGABRT or SIGTERM), assert _SIGNAL_LOCK.
*/
if ( siglock )
_mlock(_SIGNAL_LOCK);
__try {
/*
* From here on, sigact is assumed to be a pointer to a user-supplied
* handler.
*/
/*
* For signals which correspond to exceptions, set the pointer
* to the EXCEPTION_POINTERS structure to NULL
*/
if ( (signum == SIGFPE) || (signum == SIGSEGV) ||
(signum == SIGILL) ) {
oldpxcptinfoptrs = ptd->_tpxcptinfoptrs;
ptd->_tpxcptinfoptrs = NULL;
/*
* If signum is SIGFPE, also set _fpecode to
* _FPE_EXPLICITGEN
*/
if ( signum == SIGFPE ) {
oldfpecode = ptd->_tfpecode;
ptd->_tfpecode = _FPE_EXPLICITGEN;
}
}
/*
* Reset the action to SIG_DFL and call the user specified handler
* routine.
*/
if ( signum == SIGFPE )
/*
* for SIGFPE, must reset the action for all of the floating
* point exceptions
*/
for ( indx = _First_FPE_Indx ;
indx < _First_FPE_Indx + _Num_FPE ;
indx++ )
{
( (struct _XCPT_ACTION *)(ptd->_pxcptacttab) +
indx )->XcptAction = SIG_DFL;
}
else
*psigact = (_PHNDLR) _encoded_null();
}
__finally {
if ( siglock )
_munlock(_SIGNAL_LOCK);
}
if ( signum == SIGFPE )
/*
* Special code to support old SIGFPE handlers which
* expect the value of _fpecode as the second argument.
*/
(*(void (__cdecl *)(int,int))sigact)(SIGFPE,
ptd->_tfpecode);
else
(*sigact)(signum);
/*
* For signals which correspond to exceptions, restore the pointer
* to the EXCEPTION_POINTERS structure.
*/
if ( (signum == SIGFPE) || (signum == SIGSEGV) ||
(signum == SIGILL) ) {
ptd->_tpxcptinfoptrs = oldpxcptinfoptrs;
/*
* If signum is SIGFPE, also restore _fpecode
*/
if ( signum == SIGFPE )
ptd->_tfpecode = oldfpecode;
}
return(0);
}
/***
*struct _XCPT_ACTION *siglookup(int signum) - look up exception-action table
* entry for signal.
*
*Purpose:
* Find the first entry int _XcptActTab[] whose SigNum field is signum.
*
*Entry:
* int signum - C signal type (e.g., SIGINT)
*
*Exit:
* If successful, pointer to the table entry. If no such entry, NULL is
* returned.
*
*Exceptions:
*
*******************************************************************************/
static struct _XCPT_ACTION * __cdecl siglookup (
int signum,
struct _XCPT_ACTION *pxcptacttab
)
{
struct _XCPT_ACTION *pxcptact = pxcptacttab;
/*
* walk thru the _xcptactab table looking for the proper entry. note
* that in the case where more than one exception corresponds to the
* same signal, the first such instance in the table is the one
* returned.
*/
while ( (pxcptact->SigNum != signum) &&
(++pxcptact < pxcptacttab + _XcptActTabCount) ) ;
if ( (pxcptact < (pxcptacttab + _XcptActTabCount)) &&
(pxcptact->SigNum == signum) )
/*
* found a table entry corresponding to the signal
*/
return(pxcptact);
else
/*
* found no table entry corresponding to the signal
*/
return(NULL);
}
/***
*_PHNDLR __cdecl __get_sigabrt(void) - return the SIGABRT signal handling function
*
*Purpose:
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
_PHNDLR __cdecl __get_sigabrt(void)
{
return (_PHNDLR) DecodePointer(abort_action);
}
/***
*int *__fpecode(void) - return pointer to _fpecode field of the tidtable entry
* for the current thread
*
*Purpose:
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
int * __cdecl __fpecode (
void
)
{
return( &(_getptd()->_tfpecode) );
}
/***
*void **__pxcptinfoptrs(void) - return pointer to _pxcptinfoptrs field of the
* tidtable entry for the current thread
*
*Purpose:
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
void ** __cdecl __pxcptinfoptrs (
void
)
{
return( &(_getptd()->_tpxcptinfoptrs) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -