⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winsig.c

📁 C标准库源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                if ( ++pxcptact >= ((struct _XCPT_ACTION *)(ptd->_pxcptacttab)
                                   + _XcptActTabCount) )
#else  /* _MT */
                if ( ++pxcptact >= (_XcptActTab + _XcptActTabCount) )
#endif  /* _MT */
                    break;
        }

sigretok:
        return(oldsigact);

sigreterror:
        errno = EINVAL;
        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;

#ifdef _MT
        int siglock = 0;
        _ptiddata ptd;
#endif  /* _MT */

        switch (signum) {

                case SIGINT:
                        sigact = *(psigact = &ctrlc_action);
#ifdef _MT
                        siglock++;
#endif  /* _MT */
                        break;

                case SIGBREAK:
                        sigact = *(psigact = &ctrlbreak_action);
#ifdef _MT
                        siglock++;
#endif  /* _MT */
                        break;

                case SIGABRT:
                        sigact = *(psigact = &abort_action);
#ifdef _MT
                        siglock++;
#endif  /* _MT */
                        break;

                case SIGTERM:
                        sigact = *(psigact = &term_action);
#ifdef _MT
                        siglock++;
#endif  /* _MT */
                        break;

                case SIGFPE:
                case SIGILL:
                case SIGSEGV:
#ifdef _MT
                        ptd = _getptd();
                        sigact = *(psigact = &(siglookup( signum,
                            ptd->_pxcptacttab )->XcptAction));
#else  /* _MT */
                        sigact = *(psigact = &(siglookup( signum )->
                            XcptAction));
#endif  /* _MT */
                        break;

                default:
                        /*
                         * unsupported signal, return an error
                         */
                        return (-1);
        }

#ifdef _MT
        /*
         * if signum is one of the 'process-wide' signals (i.e., SIGINT,
         * SIGBREAK, SIGABRT or SIGTERM), assert _SIGNAL_LOCK.
         */
        if ( siglock )
                _mlock(_SIGNAL_LOCK);
#endif  /* _MT */

        /*
         * If the current action is SIG_IGN, just return
         */
        if ( sigact == SIG_IGN ) {

#ifdef _MT
                if ( siglock )
                        _munlock(_SIGNAL_LOCK);
#endif  /* _MT */
                return(0);
        }

        /*
         * If the current action is SIG_DFL, take the default action
         */
        if ( sigact == SIG_DFL ) {

#ifdef _MT
                if ( siglock )
                        _munlock(_SIGNAL_LOCK);
#endif  /* _MT */
                /*
                 * The current default action for all of the supported
                 * signals is to terminate with an exit code of 3.
                 *
                 */
                _exit(3);
        }

        /*
         * 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) ) {
#ifdef _MT
                oldpxcptinfoptrs = ptd->_tpxcptinfoptrs;
                ptd->_tpxcptinfoptrs = NULL;
#else  /* _MT */
                oldpxcptinfoptrs = _pxcptinfoptrs;
                _pxcptinfoptrs = NULL;
#endif  /* _MT */

                 /*
                  * If signum is SIGFPE, also set _fpecode to
                  * _FPE_EXPLICITGEN
                  */
                if ( signum == SIGFPE ) {
#ifdef _MT
                        oldfpecode = ptd->_tfpecode;
                        ptd->_tfpecode = _FPE_EXPLICITGEN;
#else  /* _MT */
                        oldfpecode = _fpecode;
                        _fpecode = _FPE_EXPLICITGEN;
#endif  /* _MT */
                }
        }

        /*
         * 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++ )
                {
#ifdef _MT
                        ( (struct _XCPT_ACTION *)(ptd->_pxcptacttab) +
                          indx )->XcptAction = SIG_DFL;
#else  /* _MT */
                        _XcptActTab[indx].XcptAction = SIG_DFL;
#endif  /* _MT */
                }
        else
                *psigact = SIG_DFL;

#ifdef _MT
        if ( siglock )
                _munlock(_SIGNAL_LOCK);
#endif  /* _MT */

        if ( signum == SIGFPE )
                /*
                 * Special code to support old SIGFPE handlers which
                 * expect the value of _fpecode as the second argument.
                 */
#ifdef _MT
                (*(void (__cdecl *)(int,int))sigact)(SIGFPE,
                    ptd->_tfpecode);
#else  /* _MT */
                (*(void (__cdecl *)(int,int))sigact)(SIGFPE, _fpecode);
#endif  /* _MT */
        else
                (*sigact)(signum);

        /*
         * For signals which correspond to exceptions, restore the pointer
         * to the EXCEPTION_POINTERS structure.
         */
        if ( (signum == SIGFPE) || (signum == SIGSEGV) ||
            (signum == SIGILL) ) {
#ifdef _MT
                ptd->_tpxcptinfoptrs = oldpxcptinfoptrs;
#else  /* _MT */
                _pxcptinfoptrs = oldpxcptinfoptrs;
#endif  /* _MT */

                 /*
                  * If signum is SIGFPE, also restore _fpecode
                  */
                if ( signum == SIGFPE )
#ifdef _MT
                        ptd->_tfpecode = oldfpecode;
#else  /* _MT */
                        _fpecode = oldfpecode;
#endif  /* _MT */
        }

        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:
*
*******************************************************************************/

#ifdef _MT

static struct _XCPT_ACTION * __cdecl siglookup (
        int signum,
        struct _XCPT_ACTION *pxcptacttab
        )
{
        struct _XCPT_ACTION *pxcptact = pxcptacttab;

#else  /* _MT */

static struct _XCPT_ACTION * __cdecl siglookup(int signum)
{
        struct _XCPT_ACTION *pxcptact = _XcptActTab;

#endif  /* _MT */
        /*
         * 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.
         */
#ifdef _MT

        while ( (pxcptact->SigNum != signum) &&
                (++pxcptact < pxcptacttab + _XcptActTabCount) ) ;

#else  /* _MT */

        while ( (pxcptact->SigNum != signum) &&
                (++pxcptact < _XcptActTab + _XcptActTabCount) ) ;

#endif  /* _MT */

#ifdef _MT
        if ( (pxcptact < (pxcptacttab + _XcptActTabCount)) &&
#else  /* _MT */
        if ( (pxcptact < (_XcptActTab + _XcptActTabCount)) &&
#endif  /* _MT */
             (pxcptact->SigNum == signum) )
                /*
                 * found a table entry corresponding to the signal
                 */
                return(pxcptact);
        else
                /*
                 * found no table entry corresponding to the signal
                 */
                return(NULL);
}

#ifdef _MT

/***
*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) );
}

#endif  /* _MT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -