12
我的程序经过这样的循环:当它等待输入,这恰好是从插座中断阻止读
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
读取功能块。我想处理SIGINT并基本告诉它如果正在读取并停止读取函数,然后调用任意函数。做这个的最好方式是什么?
我的程序经过这样的循环:当它等待输入,这恰好是从插座中断阻止读
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
读取功能块。我想处理SIGINT并基本告诉它如果正在读取并停止读取函数,然后调用任意函数。做这个的最好方式是什么?
从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
当您的进程收到信号时,read()
将返回并且errno
的值将设置为EINTR
。
根据您提供什么,发送SIGINT(通过Ctrl + C)只是结束程序。 – kaykun 2011-06-06 09:06:07
@ kaykun,只有这是程序的最后一行。您可以在重新启动传输的'while'块之后添加更多行,您可以删除特定客户端并继续执行程序的主循环,您可以启动与用户的交互式shell,以询问接下来要执行的操作没有什么说这必须终止程序。 – sarnold 2011-06-06 09:13:25
@sarnold不正确,至少对我来说,无论我在while循环后添加什么,发送SIGINT时程序都会终止,这对几乎所有其他命令行程序都是一样的。 – kaykun 2011-06-06 09:21:58