如何编写C语言程序使Ctrl+Break失效?
有好几种方法可以使Ctrl+Break功能失效,这里只讨论两种最常用的方法。
第一种方法是用DOS来解除Ctrl+Break功能。你可能用DOS中断21H的33H函数来得到或设置Ctrl+Break检查标志,该标志告诉DOS是否在Ctrl+Break按下时对其进行处理。下面的例子说明了这种方法:
# include <stdio. h>
# include <dos. h>
void main(int argc,char **argv)
{
union REGS regs;
int ctrlBreakFlag ;
/ * find out the curre.nt state of the flag * /
regs. x. ax= 0x3300 ; / * subfunction 0 gets flag state */
int86 (0x21, ®s, ®s) ;
ctrlBreakFlag == rags. h. dl ; / * save flag value from DL * /
/ * set the state of the flag to disable Ctrl+Break * /
regs. x. ax=0x3301;
regs. h. dl = 0 ; / * disable checking * /
int86(0x21,®s, ®s) ; /* subfunction 1 sets flag state * /
}
上例首先调用DOS来查询Ctrl+Break检查标志的当前状态,并将其存入ctrlBreakFlag中。DOS调用的返回值存在DL中,如果解除了Ctrl+Break检查,则该值为O;如果允许Ctrl+Break检查,则该值为1。接着,上例清除DL并调用DOS的设置Ctrl+Break标志函数来解除Ctrl+Break检查。在调用上述函数重新设置Ctrl+Break标志之前,此次所设置的状态将一直保留。上例没有用到子函数02(AX一0x3302),该函数能同时得到并设置Ctrl+Break标志的状态,为了完成这项任务,你应该把0x3302放到AX中,把要求的Ctrl+Break标志状态放到DL中,然后进行中断,并把原来的状态从DL中存入ctrlBreakFlag中。
第二种方法是使用信号(signal)。信号是从过去的UNIX时代继承下来的。信号函数的作用是在某些事件发生时通知程序员,这些事件之一就是用户中断——在DOS下就是Ctrl+Break事件。下面的例子说明了如何用Microsoft的signal()函数来捕获Ctrl+Break事件并作出反应(假设允许Ctrl+Break检查):
# include <[stdio. h>
# include <signal. h>
int exitHandler (void) ;
int main (int argc,char ** argv)
{
int quitFlag = 0 ;
/ * Trap all Ctrl+Breaks * /
signal (SIGINT, (void (__cdecl * ) (int))exitHandler);
/ * Sit in infinite loop until user presses Ctrl+Break * /
while (quitFlag = = 0)
printf (" % s\", (argv > 1 ) ? argv [ 1 ] : "Waiting for Ctrl + Break" ) ;
}
/ * Ctrl+Break event handler function * /
int exitHandler ()
{
char ch ;
/ * Disable Ctrl+Break handling while inside the handler * /
signal (SIGINT, SIG_ IGN ) ;
/ * Since it was an "interrupt",clear keyboard input buffer * /
fflush(stdin) ;
/ * Ask if user really wants to quit program * /
printf("\nCtrl+Break occurred. Do you wish to exit this program?
→(Y or N)");
/ * Flush output buffer as well * /
fflush (stdout) ;
/ * Get input from user, print character and newline * /
ch =getche ( ) ;
printf("\n" ) ;
/ * If user said yes, leave program * /
if(toupper (eh) = 'Y' )
exit (0) ;
/ * Reenable Ctrl+Break handling * /
signal (SIGINT, (void (__cdecl * ) (int))exitHandler) ;
return(0) ;
}
上例的好处在于每当按下Ctrl+Break时都会调用一个函数,也就是说,你可以选择将要作出的反应一一你可以忽略这个事件,相当于解除Ctrl+Break功能;你也可以作出所需的其它任何反应;上例的另一个好处是当程序退出时,Ctrl+Break的正常操作就会恢复,不需要人为的干预。
第一种方法是用DOS来解除Ctrl+Break功能。你可能用DOS中断21H的33H函数来得到或设置Ctrl+Break检查标志,该标志告诉DOS是否在Ctrl+Break按下时对其进行处理。下面的例子说明了这种方法:
# include <stdio. h>
# include <dos. h>
void main(int argc,char **argv)
{
union REGS regs;
int ctrlBreakFlag ;
/ * find out the curre.nt state of the flag * /
regs. x. ax= 0x3300 ; / * subfunction 0 gets flag state */
int86 (0x21, ®s, ®s) ;
ctrlBreakFlag == rags. h. dl ; / * save flag value from DL * /
/ * set the state of the flag to disable Ctrl+Break * /
regs. x. ax=0x3301;
regs. h. dl = 0 ; / * disable checking * /
int86(0x21,®s, ®s) ; /* subfunction 1 sets flag state * /
}
上例首先调用DOS来查询Ctrl+Break检查标志的当前状态,并将其存入ctrlBreakFlag中。DOS调用的返回值存在DL中,如果解除了Ctrl+Break检查,则该值为O;如果允许Ctrl+Break检查,则该值为1。接着,上例清除DL并调用DOS的设置Ctrl+Break标志函数来解除Ctrl+Break检查。在调用上述函数重新设置Ctrl+Break标志之前,此次所设置的状态将一直保留。上例没有用到子函数02(AX一0x3302),该函数能同时得到并设置Ctrl+Break标志的状态,为了完成这项任务,你应该把0x3302放到AX中,把要求的Ctrl+Break标志状态放到DL中,然后进行中断,并把原来的状态从DL中存入ctrlBreakFlag中。
第二种方法是使用信号(signal)。信号是从过去的UNIX时代继承下来的。信号函数的作用是在某些事件发生时通知程序员,这些事件之一就是用户中断——在DOS下就是Ctrl+Break事件。下面的例子说明了如何用Microsoft的signal()函数来捕获Ctrl+Break事件并作出反应(假设允许Ctrl+Break检查):
# include <[stdio. h>
# include <signal. h>
int exitHandler (void) ;
int main (int argc,char ** argv)
{
int quitFlag = 0 ;
/ * Trap all Ctrl+Breaks * /
signal (SIGINT, (void (__cdecl * ) (int))exitHandler);
/ * Sit in infinite loop until user presses Ctrl+Break * /
while (quitFlag = = 0)
printf (" % s\", (argv > 1 ) ? argv [ 1 ] : "Waiting for Ctrl + Break" ) ;
}
/ * Ctrl+Break event handler function * /
int exitHandler ()
{
char ch ;
/ * Disable Ctrl+Break handling while inside the handler * /
signal (SIGINT, SIG_ IGN ) ;
/ * Since it was an "interrupt",clear keyboard input buffer * /
fflush(stdin) ;
/ * Ask if user really wants to quit program * /
printf("\nCtrl+Break occurred. Do you wish to exit this program?
→(Y or N)");
/ * Flush output buffer as well * /
fflush (stdout) ;
/ * Get input from user, print character and newline * /
ch =getche ( ) ;
printf("\n" ) ;
/ * If user said yes, leave program * /
if(toupper (eh) = 'Y' )
exit (0) ;
/ * Reenable Ctrl+Break handling * /
signal (SIGINT, (void (__cdecl * ) (int))exitHandler) ;
return(0) ;
}
上例的好处在于每当按下Ctrl+Break时都会调用一个函数,也就是说,你可以选择将要作出的反应一一你可以忽略这个事件,相当于解除Ctrl+Break功能;你也可以作出所需的其它任何反应;上例的另一个好处是当程序退出时,Ctrl+Break的正常操作就会恢复,不需要人为的干预。