处理 EINTR(使用 goto?)

2023-12-21

背景:这是一个后续问题这个线程 https://stackoverflow.com/questions/2957759/using-gprof-with-sockets关于在 C++ (Linux/GCC) 中处理系统调用的 EINTR。无论我是否打算分析我的应用程序,似乎我都应该处理系统调用设置errno to EINTR作为一个特例。有many https://stackoverflow.com/questions/24451/goto-usage, many https://stackoverflow.com/questions/46586/goto-still-considered-harmful, many http://xkcd.com/292/关于使用的意见goto.

我的问题:是系统调用设置errno to EINTR一个案例goto被认为是名义上的?如果没有,那么您建议如何转换以下代码来处理EINTR?

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

提前致谢!
Cheers,
-Chris

UPDATE:根据下面的答案,我最终编写了以下宏:

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

希望这对其他人有帮助!


据我所知,套接字系统调用无法返回并将 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;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

处理 EINTR(使用 goto?) 的相关文章

随机推荐