在很多的系统调用中,在错误返回时都会有一个EINTR的值。这个返回值的描述时在系统调用执行时,遇到发生信号。
今天写了个小程序来完成这个事,程序如下:
- #include <stdio.h>
-
#include <unistd.h>
-
#include <signal.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <netinet/ip.h>
-
#include <netinet/in.h>
-
void alarm_handler(int signo)
-
{
-
printf ("here is the alarm\n");
-
alarm(1);
-
return ;
-
}
-
-
int main(int argc, char *argv[])
-
{
-
int sockfd = -1;
-
int ret = 0;
-
struct sockaddr_in server_addr;
-
struct sockaddr_in client_addr;
-
socklen_t addr_len = 0;
-
struct sigaction sa;
-
-
sa.sa_handler = alarm_handler;
-
sa.sa_flags = 0;
-
sigaction(SIGALRM, &sa, NULL);
-
alarm(1);
-
sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
if (sockfd < 0)
-
{
-
perror("socket fail:");
-
goto out;
-
}
-
server_addr.sin_family = AF_INET;
-
server_addr.sin_addr.s_addr = 0;
-
server_addr.sin_port = 0x1234;
-
ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
-
if (ret < 0)
-
{
-
perror("bind fail:");
-
goto out;
-
}
-
ret = listen(sockfd, 100);
-
if (ret < 0)
-
{
-
perror("listen fail:");
-
goto out;
-
}
-
-
ret = accept(sockfd, (struct sockaddr *)&client_addr, &addr_len);
-
if (ret < 0)
-
{
-
perror("accept fail:");
-
goto out;
-
}
-
out:
-
if (sockfd >= 0)
-
{
-
close(sockfd);
-
sockfd = -1;
-
}
-
return 0;
-
}
编译之后执行:
- here is the alarm
-
accept fail:: Interrupted system call
约1秒中之后出现上述输出。终于构造了一个返回EINTR的调用。对于这个程序有几点说明:
- 需要使用sigaction而不是signal注册信号处理函数的原因是因为,signal默认的flag包含了SA_RESTART,这样造成了,accept中断后不会返回而是在signal处理函数之后继续执行。
- 使用alarm来定时产生一个中断
这个小程序也解决了自己的一个疑惑,之前使用signal时总是不成功,原因就是SA_RESTART。
阅读(2628) | 评论(0) | 转发(0) |