处理 EINTR(使用 goto?)
背景:这是此帖子的后续问题,内容涉及在 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()" )
希望这对其他人有帮助!
Background: This is a follow-up question to this thread about handling EINTR for system calls in C++ (Linux/GCC). Regardless of whether or not I intend to profile my application, it seems like I should be handling system calls setting errno
to EINTR
as a special case. There are many, many, many opinions about the use of goto
.
My question: is a system call setting errno
to EINTR
a case where goto
is considered nominal? If not, then how would you suggest converting the following code to handle EINTR
?
if ( ( sock_fd = ::socket( domain, type, protocol ) ) < 0 ) {
throw SocketException( "Socket::Socket() -> ::socket()", errno );
}
Thanks in advance!
Cheers,
-Chris
UPDATE: Based on the answers below, I wound up writing the following macro:
#define SOCK_SYSCALL_TRY(call,error) \
while ( (call) < 0 ) { \
switch ( errno ) { \
case EINTR: \
continue; \
default: \
throw SocketException( (error), errno ); \
} \
} \
Which is used to transform my original snippet to this example:
SOCK_SYSCALL_TRY( sock_fd = ::socket( domain, type, protocol ), "Socket::Socket() -> ::socket()" )
Hope this helps someone else!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知,套接字系统调用无法返回并将 errno 设置为 EINTR。
对于其他情况,我使用循环:
As far as I know the socket system call can't return with errno set to EINTR.
For other cases I use a loop:
我编写了一个 FTP 服务器程序,但从来不需要使用 goto。我通常构造这样的可中断系统调用:
EINTR 意味着您的服务器已捕获信号,并且大多数时候处理该信号很重要。
I programed an FTP server and I never had to use goto. I usually constructed interruptable system-calls like this:
EINTR means your server has caught a signal, and it is most of the time important to handle that signal.