2013-03-06 112 views
1

工作这个程序CTRL-C处理程序无法正常

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <windows.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 

void INThandler(int);    

int main(void) 
{ 
    signal(SIGINT, INThandler);  

    char data[128]; 

    int n; 

    while((n=read(0, data, 128)) > 0) 
    { 
    if(data[n] = '\n') break; 
    } 

    data[n] ='\0'; 

    printf("%s", data); 

    return 0; 
} 

void INThandler(int sig) 
{ 
    char c; 

    signal(sig, SIG_IGN);    
    printf("OUCH, did you hit Ctrl-C?\n"  
      "Do you really want to quit? [y/n] "); 
    c = getchar();      
    if (c == 'y' || c == 'Y')   
     exit(0);      
    else 
     signal(SIGINT, INThandler); 
} 

无法处理CTRL-C,但在那输入终止。 如果我更换由

while (1)       
Sleep(1); 

的处理函数被调用和工程处理程序安装和收益之间的一切,但我想有阅读()在那里。

编辑:这个节目回首,我发现我有

if(data[n] = '\n') break; 

我写了“=”而不是“==”,但使用后,它不能正确和我的工作不明白为什么。它不应该是检测'\ n'的比较吗? 另外,我搞砸了缓冲区,但我不能保持输入,如果我打CTRL-C。

回答

0

这是因为您使用的read(2)的执行不允许。下面是当我编译你的程序,执行它,然后按^ C我得到什么:

$ ./program 
^COUCH, did you hit Ctrl-C? 
Do you really want to quit? [y/n] y 
$ 

,或者如果我回答n并输入一些数据:

$ ./program 
^COUCH, did you hit Ctrl-C? 
Do you really want to quit? [y/n] n 
test 
test 
$ 

由于read(2)是一个系统调用,它取决于您使用的系统。我使用Linux(3.2.0-4-686-pae),在这里它的行为是正确的。也许你应该考虑使用scanf(3)fread(3)而不是stdio(3)而不是你正在使用的平台(我认为是win32)?或者也可以使用不同的实现方式,例如从CygwinMinGW

+0

我明白了,所以它取决于SO。到目前为止,我没有使用Windows的问题,然后在Unix上进行测试。谢谢。 – Aleister 2013-03-06 13:35:47

1

示例代码并没有考虑到占两个问题:

  1. read()将中止它的工作,如果它的进程收到的信号(见man 2 read
  2. 它只能保证一些功能,他们可以可以从信号处理函数中调用(参见man 7 signal)。 printf()getch()不要不是属于这组“保存”功能。

第一个问题可以通过更多不同的方式来解决,以处理read()返回的值。我应该计算已经读取了多少数据,以及传递给read()的缓冲区的一些智能调整。

关于第二个问题,read()write()是选择执行信号处理程序的输入/输出功能的功能,因为它们被上面提到的手册页列为“保存”功能。