背景:这是这条线关于在C++ (Linux/GCC)中处理系统调用的EINTR的后续问题。无论我是否打算分析我的应用程序,我似乎都应该处理系统调用,将errno设置为EINTR作为特例。许多,许多,许多对goto的使用有不同的看法。
我的问题是:是将errno设置为EINTR的系统调用,在这种情况下,goto被认为是名义的?如果没有,那么如何建议将以下代码转换为处理EINTR
if ( ( sock_fd = ::socket( domain, type, protocol ) ) < 0 ) {
throw SocketException( "Socket::Socket() -> ::socket()", errno );
}提前感谢!
干杯,
-Chris
更新:基于下面的答案,我编写了以下宏:
#define SOCK_SYSCALL_TRY(call,error) \
while ( (call) < 0 ) { \
switch ( errno ) { \
case EINTR: \
continue; \
default: \
throw SocketException( (error), errno ); \
} \
} \它用于将我的原始片段转换为下面的示例:
SOCK_SYSCALL_TRY( sock_fd = ::socket( domain, type, protocol ), "Socket::Socket() -> ::socket()" )希望这能帮到别人!
发布于 2010-06-02 13:44:28
据我所知,当errno设置为EINTR时,套接字系统调用无法返回。对于其他情况,我使用循环:
while ((::connect(sock, (struct sockaddr *)&destAddress, sizeof(struct sockaddr))) == -1) {
if (errno == EINTR) {
LOGERROR("connect interrupted, retry");
continue;
} else if (errno == EINPROGRESS) {
break;
} else {
LOGERROR("connect failed, errno: " << errno);
return -1;
}
}发布于 2010-06-02 13:46:28
我编写了一个FTP服务器,我从来不用使用goto。我通常构建这样的可中断系统:
while( (ret =
splice_stream( data, NULL, file, &block_offset,
XFER_BLOCK_SIZE )) == -1 )
{
switch( errno )
{
case EINTR:
if( server_handle_signal() )
return FTP_QUIT;
else
continue;
break;
case EPIPE:
case ECONNRESET:
return FTP_ABOR;
default:
log_fatal("Splice error: %m\n");
return FTP_ERROR;
}
}EINTR意味着您的服务器已经捕获了一个信号,并且在大多数情况下处理该信号非常重要。
https://stackoverflow.com/questions/2958114
复制相似问题