您的位置:首页 > 运维架构 > Linux

linux api笔记(7):系统调用如何摆脱信号的干扰

2010-04-19 16:11 417 查看
在linux环境下编程有一个很让人头疼的问题就是信号对系统调用的干扰,在系统调用过程中如果受到信号的干扰,

部分系统调用会将errno设置成EINTR,我们不得不编写下面的错误处理代码来防止这种情况的发生:

syscall:
int ret = syscall(...);
if (ret < 0 && EINTER == errno)
goto syscall;
else if(ret < 0)
...
else
...


一次又一次的编写的话真的很烦,而前端时间我在chrome的源代码中找到的一段代码正好解决了这种丑陋的编码:

#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#define HANDLE_EINTR(x) ({ /
typeof(x) __eintr_code__; /
do { /
__eintr_code__ = x; /
} while(__eintr_code__ < 0 && EINTR == errno); /
__eintr_code__; /
})
int main()
{
int fd = 0;
char buf[1024];
fd = open("hello world", O_RDWR);
HANDLE_EINTR(read(fd,buf, sizeof(buf)));
close(fd);
return 0;
}


当然我们也不是只要碰到系统调用就使用HANDLE_EINTR,一个系统调用函数至少要满足两个条件的时候才能使用:

1)返回值类型为int

2)会受到信号的干扰,也就是说有可能将errno设置成EINTR(这就需要我们查man手册了)。上面的open函数就

不会受到信号的干扰,所以就不能使用这个宏。

至少到目前为止,我发现凡是能够将errno设置成EINTR的系统函数的返回值类型都是int,并且当出错的时候

返回值小于0。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: