5

在规范和两个实现中:

  • 根据 POSIX,dup2()可能会返回 EINTR。
  • linux 手册页将其列为允许的。
  • FreeBSD 手册页表明它从未返回。这是一个错误吗 - 因为它的紧密实现可以 EINTR(至少对于 TCP 徘徊,如果没有别的)。

实际上,Linux 可以返回 EINTRdup2()吗?据推测,如果是这样,那将是因为close()决定等待并且信号到达(TCP 逗留或在关闭时尝试同步的狡猾的文件系统驱动程序)。

实际上,FreeBSD 是否保证不返回 EINTR dup2()?在这种情况下,它一定不会费心等待旧 fd 上的任何未完成的操作,而是简单地取消链接 fd。

当POSIXdup2()指的是“关闭”(不是斜体)而不是引用实际函数时,它是什么意思close()- 我们是否理解它只是以非正式的方式“关闭”它(取消链接文件描述符),还是它试图说效果应该就像close()函数首先被调用然后dup2()被原子调用一样。

如果fildes2已经是有效的打开文件描述符,则应首先将其关闭,除非fildes等于fildes2在这种情况下dup2()应返回fildes2而不关闭它。

如果dup2() 确实必须关闭,等待,然后以原子方式复制,这对实现者来说将是一场噩梦!close()这比惨败的 EINTR 要糟糕得多。懦弱的 POSIX 甚至没有说在 EINTR 的情况下是否发生了重复......

4

2 回答 2

1

以下是 C/POSIX 库文档中关于标准 Linux 实现的相关信息:

 If OLD and NEW are different numbers, and OLD is a valid
 descriptor number, then `dup2' is equivalent to:

      close (NEW);
      fcntl (OLD, F_DUPFD, NEW)

 However, `dup2' does this atomically; there is no instant in the
 middle of calling `dup2' at which NEW is closed and not yet a
 duplicate of OLD.

它列出了dupdup2作为EBADFEINVAL和的可能返回的错误值EMFILE,而没有其他值。该文档指出,所有可以返回 EINTR 的函数都按此类列出,这表明这些函数没有。请注意,这些是通过 实现fcntl的,而不是对 的调用close

于 2013-04-10T19:46:09.057 回答
0

8 years later this still seems to be undocumented. I looked at the linux sources and my conclusion is that dup2 can't return EINTR in a current version of Linux.

In particular, the function do_dup2 in fs/file.c ignores the return value of filp_close, which is what can cause close to return EINTR in some cases (see fs/open.c and fs/file.c).

The way dup2 works is it first makes the atomic file descriptor update, and then waits for any flushing that needs to happen on close. Any errors happening on flush are simply ignored.

于 2021-12-28T18:00:09.107 回答