2011-06-06 125 views
12

我的程序经过这样的循环:当它等待输入,这恰好是从插座中断阻止读

... 
while(1){ 
    read(sockfd,buf,sizeof(buf)); 
    ... 
} 

读取功能块。我想处理SIGINT并基本告诉它如果正在读取并停止读取函数,然后调用任意函数。做这个的最好方式是什么?

回答

14

read(2)

EINTR The call was interrupted by a signal before any data 
      was read; see signal(7). 

如果你修改你的代码看起来更像:

cont = 1; 
while (1 && cont) { 
    ret = read(sockfd, buf, sizeof(buf)); 
    if (ret < 0 && errno == EINTR) 
     cont = arbitrary_function(); 
} 

这让arbitrary_function()决定是否read(2)应重新审理或者不。

更新

你需要为了得到read(2)EINTR行为来处理信号:

#include<unistd.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<signal.h> 
#include<errno.h> 

int interrupted; 

void handle_int(num) { 
    interrupted = 1; 
} 

int main(void){ 
    char buf[9001]; 
    struct sigaction int_handler = {.sa_handler=handle_int}; 
    sigaction(SIGINT,&int_handler,0); 
    while(!interrupted){ 
    printf("interrupted: %d\n", interrupted); 
    if(read(0,buf,sizeof(buf))<0){ 
     if(errno==EINTR){ 
     puts("eintr"); 
     }else{ 
     printf("%d\n",errno); 
     } 
     puts("."); 
    } 
    } 
    puts("end"); 
    return 0; 
} 

给出输出:

$ ./foo 
interrupted: 0 
hello 
interrupted: 0 
^Ceintr 
. 
end 
+0

根据您提供什么,发送SIGINT(通过Ctrl + C)只是结束程序。 – kaykun 2011-06-06 09:06:07

+0

@ kaykun,只有这是程序的最后一行。您可以在重新启动传输的'while'块之后添加更多行,您可以删除特定客户端并继续执行程序的主循环,您可以启动与用户的交互式shell,以询问接下来要执行的操作没有什么说这必须终止程序。 – sarnold 2011-06-06 09:13:25

+0

@sarnold不正确,至少对我来说,无论我在while循环后添加什么,发送SIGINT时程序都会终止,这对几乎所有其他命令行程序都是一样的。 – kaykun 2011-06-06 09:21:58

2

当您的进程收到信号时,read()将返回并且errno的值将设置为EINTR