简体   繁体   English

如何知道Linux系统调用是否可重启?

[英]How to know if a Linux system call is restartable or not?

Some system calls can be restarted transparently by the Kernel if the SA_RESTART flag is used when installing the signal handler, according to man signal(7) : 根据man 信号(7) ,如果在安装信号处理程序时使用SA_RESTART标志,则内核可以透明地重启某些系统调用:

If a blocked call to one of the following interfaces is interrupted by a signal handler, then the call will be automatically restarted after the signal handler returns if the SA_RESTART flag was used ; 如果对信号处理程序中断对以下某个接口的阻塞调用, 则在使用SA_RESTART标志后,如果信号处理程序返回,则将自动重新启动该调用 otherwise the call will fail with the error EINTR: 否则呼叫将失败并显示错误EINTR:

Then it mentions some system calls that can (and can not) be restarted, but does not mention close() in either places, how would I know if close() , or any other function, is restartable or not ? 然后它提到了一些可以(并且不能)重新启动的系统调用,但是在任何一个地方都没有提到close() ,我怎么知道close()或任何其他函数是否可以重启? does POSIX specify it or is it a Linux-specific behaviour ? POSIX指定它还是特定于Linux的行为? where can I find more info ? 我在哪里可以找到更多信息?

close is a rather special case. close是一个相当特殊的情况。 Not only is it not restartable on Linux; 它不仅不能在Linux上重启; when close returns with EINTR on Linux, it has actually already succeeded, and making another call to close will fail with EBADF in single-threaded processes and cause extremely dangerous file-descriptor races in multi-threaded processes. 当Linux上的EINTR close返回时,它实际上已经成功,并且在单线程进程中使用EBADF进行另一次close调用将失败, EBADF在多线程进程中导致极其危险的文件描述符争用。

As of the published POSIX 2008, this behavior is permitted: 截至发布的POSIX 2008,允许此行为:

If close() is interrupted by a signal that is to be caught, it shall return -1 with errno set to [EINTR] and the state of fildes is unspecified. 如果close()被要捕​​获的信号中断,它将返回-1,并将errno设置为[EINTR]并且未指定fildes的状态。

This issue was raised with the Austin Group (as Issue #529 ) and it was resolved to revise the specification such that returning with EINTR means the file descriptor is still open; 这个问题是由Austin Group提出的( 问题#529 ),并且决定修改规范,以便用EINTR返回意味着文件描述符仍然是打开的; this is contrary to the current Linux behavior. 这与当前的Linux行为相反。 If the file descriptor has already been closed at the time the signal is handled, the close function is now required to return with EINPROGRESS instead of EINTR . 如果在处理信号时文件描述符已经关闭,则现在需要使用EINPROGRESS而不是EINTR返回close函数。 This can be fixed in userspace on Linux, and there is an open glibc bug report, #14627 for it, but as of this writing it has not received any response. 这可以在Linux上的用户空间中修复,并且有一个开放的glibc错误报告,#14627 ,但在撰写本文时它没有收到任何响应。

This issue also has serious implications for POSIX thread cancellation, the side effects of which are specified in terms of the side effects upon returning with EINTR . 此问题对POSIX线程取消也有严重影响,其副作用是根据EINTR返回时的副作用指定的。 There is a related issue on the Austin Group tracker, Issue #614 . 奥斯汀集团的追踪器问题#614有一个相关的问题。

As per POSIX.1-2008 , the SA_RESTART flag applies to all interruptible functions (all function which are documented to fail with EINTR ): 根据POSIX.1-2008SA_RESTART标志适用于所有可中断函数(所有记录为EINTR失败的函数):

SA_RESTART SA_RESTART

This flag affects the behavior of interruptible functions; 该标志影响可中断函数的行为; that is, those specified to fail with errno set to [EINTR]. 也就是说,指定为errno设置为[EINTR]的失败。 If set, and a function specified as interruptible is interrupted by this signal, the function shall restart and shall not fail with [EINTR] unless otherwise specified. 如果设置,并且该信号中断了指定为可中断的功能,则该功能应重新启动,除非另有说明,否则不应使用[EINTR]失败。 If an interruptible function which uses a timeout is restarted, the duration of the timeout following the restart is set to an unspecified value that does not exceed the original timeout value. 如果重新启动使用超时的可中断功能,则重新启动后超时的持续时间将设置为未指定的值,该值不会超过原始超时值。 If the flag is not set, interruptible functions interrupted by this signal shall fail with errno set to [EINTR]. 如果未设置该标志,则该信号中断的可中断功能将失败,并将errno设置为[EINTR]。

That is, the list of functions which are not restarted is Linux-specific (and probably counts as a bug). 也就是说,未重新启动的函数列表是特定于Linux的(并且可能算作错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM