首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理EINTR (与goto?)

处理EINTR (与goto?)
EN

Stack Overflow用户
提问于 2010-06-02 13:27:30
回答 2查看 1.9K关注 0票数 3

背景:这是这条线关于在C++ (Linux/GCC)中处理系统调用的EINTR的后续问题。无论我是否打算分析我的应用程序,我似乎都应该处理系统调用,将errno设置为EINTR作为特例。许多许多许多goto的使用有不同的看法。

我的问题是:是将errno设置为EINTR的系统调用,在这种情况下,goto被认为是名义的?如果没有,那么如何建议将以下代码转换为处理EINTR

代码语言:javascript
复制
if ( ( sock_fd = ::socket( domain, type, protocol ) ) < 0 ) {
  throw SocketException( "Socket::Socket() -> ::socket()", errno );
}

提前感谢!

干杯,

-Chris

更新:基于下面的答案,我编写了以下宏:

代码语言:javascript
复制
#define SOCK_SYSCALL_TRY(call,error)              \
  while ( (call) < 0 ) {                          \
    switch ( errno ) {                            \
      case EINTR:                                 \
        continue;                                 \
      default:                                    \
        throw SocketException( (error), errno );  \
    }                                             \
  }                                               \

它用于将我的原始片段转换为下面的示例:

代码语言:javascript
复制
SOCK_SYSCALL_TRY( sock_fd = ::socket( domain, type, protocol ), "Socket::Socket() -> ::socket()" )

希望这能帮到别人!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-02 13:44:28

据我所知,当errno设置为EINTR时,套接字系统调用无法返回。对于其他情况,我使用循环:

代码语言:javascript
复制
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;
    }
}
票数 4
EN

Stack Overflow用户

发布于 2010-06-02 13:46:28

我编写了一个FTP服务器,我从来不用使用goto。我通常构建这样的可中断系统:

代码语言:javascript
复制
    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意味着您的服务器已经捕获了一个信号,并且在大多数情况下处理该信号非常重要。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2958114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档