代码之家  ›  专栏  ›  技术社区  ›  Chris Tonkinson

处理EINTR(带goto?)

  •  3
  • Chris Tonkinson  · 技术社区  · 14 年前

    这是我们的后续问题 this thread 关于在C++中处理系统调用的EINTR(Linux/GCC)。不管我是否打算分析我的应用程序,似乎我应该处理系统调用设置 errno EINTR 作为特例。有 many , many many 关于使用 goto

    我的问题是: 厄尔诺 一个案子 转到 ?

    if ( ( sock_fd = ::socket( domain, type, protocol ) ) < 0 ) {
      throw SocketException( "Socket::Socket() -> ::socket()", errno );
    }
    

    提前谢谢!

    -克里斯

    更新:

    #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()" )
    

    希望这能帮助别人!

    2 回复  |  直到 7 年前
        1
  •  4
  •   macgarden    14 年前

    据我所知,如果errno设置为EINTR,socket系统调用就不能返回。 对于其他情况,我使用循环:

    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;
        }
    }
    
        2
  •  2
  •   Kasper    14 年前

        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意味着您的服务器已捕获到一个信号,处理该信号在大多数情况下都很重要。