|
1鱼币
小甲鱼老师的带你学C带你飞第一季,函数快查下面的signal 函数介绍,地址为:https://fishc.com.cn/forum.php?m ... peid%26typeid%3D583
函数结束完毕后,最后有一个举例,我在Windows 10上用codeblocks测试,程序运行后按ctrl+c没有反应,程序无法终止,只能强行关闭!
我知道小甲鱼的操作是在linux下面进行的,是不是Windows不支持该操作?因为我看了windwos官方文档,上面对signal函数的原型解释为 void __cdecl *signal(int sig, int (*func)(int, int));
不知道是不是这个原因还是因为其他?请教大神帮忙!
附上小甲鱼老师的举例源代码:
#include <stdio.h>
#include <signal.h>
void signal_handler_fun(int signal_num)
{
printf("捕获信号:%d\n", signal_num);
}
int main(void)
{
signal(SIGINT, signal_handler_fun);
while (1)
{
;
}
return 0;
}
vs里面的
- /***
- *_PHNDLR 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.
- *
- *******************************************************************************/
- _PHNDLR __cdecl signal(
- int signum,
- _PHNDLR sigact
- )
- {
- struct _XCPT_ACTION *pxcptact;
- _PHNDLR oldsigact;
- int Error=0;
- _ptiddata ptd;
- BOOL SetConsoleCtrlError = FALSE;
- /*
- * Check for values of sigact supported on other platforms but not
- * on this one. Also, make sure sigact is not SIG_DIE
- */
- if ( (sigact == SIG_ACK) || (sigact == SIG_SGE) )
- goto sigreterror;
- /*
- * Take care of all signals which do not correspond to exceptions
- * in the host OS. Those are:
- *
- * SIGINT
- * SIGBREAK
- * SIGABRT
- * SIGTERM
- *
- */
- if ( (signum == SIGINT) || (signum == SIGBREAK) || (signum == SIGABRT)
- || (signum == SIGABRT_COMPAT) || (signum == SIGTERM) ) {
- _mlock( _SIGNAL_LOCK );
- __try {
- /*
- * if SIGINT or SIGBREAK, make sure the handler is installed
- * to capture ^C and ^Break events.
- */
- if ( ((signum == SIGINT) || (signum == SIGBREAK)) &&
- !ConsoleCtrlHandler_Installed )
- {
- if ( SetConsoleCtrlHandler(ctrlevent_capture, TRUE)
- == TRUE )
- {
- ConsoleCtrlHandler_Installed = TRUE;
- }
- else
- {
- _doserrno = GetLastError();
- SetConsoleCtrlError=TRUE;
- }
- }
- switch (signum) {
- case SIGINT:
- oldsigact = (_PHNDLR) DecodePointer(ctrlc_action);
- if(sigact!=SIG_GET)
- {
- ctrlc_action = (_PHNDLR) EncodePointer(sigact);
- }
- break;
- case SIGBREAK:
- oldsigact = (_PHNDLR) DecodePointer(ctrlbreak_action);
- if(sigact!=SIG_GET)
- {
- ctrlbreak_action = (_PHNDLR) EncodePointer(sigact);
- }
- break;
- case SIGABRT:
- case SIGABRT_COMPAT:
- oldsigact = (_PHNDLR) DecodePointer(abort_action);
- if(sigact!=SIG_GET)
- {
- abort_action = (_PHNDLR) EncodePointer(sigact);
- }
- break;
- case SIGTERM:
- oldsigact = (_PHNDLR) DecodePointer(term_action);
- if(sigact!=SIG_GET)
- {
- term_action = (_PHNDLR) EncodePointer(sigact);
- }
- break;
- }
- }
- __finally {
- _munlock( _SIGNAL_LOCK );
- }
- if (SetConsoleCtrlError) {
- goto sigreterror;
- }
- goto sigretok;
- }
- /*
- * If we reach here, signum is supposed to be one the signals which
- * correspond to exceptions in the host OS. Those are:
- *
- * SIGFPE
- * SIGILL
- * SIGSEGV
- */
- /*
- * Make sure signum is one of the remaining supported signals.
- */
- if ( (signum != SIGFPE) && (signum != SIGILL) && (signum != SIGSEGV) )
- goto sigreterror;
- /*
- * Fetch the tid data table entry for this thread
- */
- ptd = _getptd_noexit();
- if (!ptd)
- goto sigreterror;
- /*
- * Check that there a per-thread instance of the exception-action
- * table for this thread. if there isn't, create one.
- */
- if ( ptd->_pxcptacttab == _XcptActTab )
- /*
- * allocate space for an exception-action table
- */
- if ( (ptd->_pxcptacttab = _malloc_crt(_XcptActTabSize)) != NULL )
- /*
- * initialize the table by copying over the contents
- * of _XcptActTab[]
- */
- (void) memcpy(ptd->_pxcptacttab, _XcptActTab,
- _XcptActTabSize);
- else
- /*
- * cannot create exception-action table, return
- * error to caller
- */
- goto sigreterror;
- /*
- * 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;
- }
- }
复制代码
|
|