【发布时间】:2013-04-02 12:57:54
【问题描述】:
在规范和两个实现中:
- 根据 POSIX,
dup2()可能会返回 EINTR。 - Linux 手册页将其列为允许。
- FreeBSD 手册页表明它从未返回。这是一个错误吗 - 因为它的紧密实现可以 EINTR(至少对于 TCP 徘徊,如果没有别的)。
实际上,Linux 可以为dup2() 返回 EINTR 吗?如果是这样,那可能是因为close() 决定等待并且信号到达(TCP 逗留或在关闭时尝试同步的狡猾的文件系统驱动程序)。
实际上,FreeBSD 是否保证不为dup2() 返回 EINTR?在这种情况下,它一定是它不会费心等待旧 fd 上的任何未完成操作,而是简单地取消链接 fd。
POSIX dup2() 指的是“关闭”(不是斜体),而不是引用实际的 close() 函数时是什么意思 - 我们是否理解它只是在以一种非正式的方式“关闭”它(取消链接文件描述符),还是试图说效果应该就像首先调用 close() 函数然后自动调用 dup2() 一样。
如果 fildes2 已经是一个有效的打开文件描述符,它应该首先被关闭,除非 fildes 等于 fildes2 在这种情况下 dup2() 将返回 fildes2 而不关闭它。
如果dup2() 确实必须关闭,等待,然后自动复制,这将是实现者的噩梦!这比 close() 惨败的 EINTR 要糟糕得多。懦弱的 POSIX 甚至没有说是否在 EINTR 的情况下发生了重复......
【问题讨论】:
-
在 Linux 中
dup2是原子的。 -
谢谢。关键是,如果
dup2()执行与close()相同的等待,这可能很难实现。close()实现取消链接 fd 表中的条目,然后等待剩余的文件结构。如果它被中断,则 fd 将关闭。如果 dup2 实现必须等待,它怎么可能是原子的 - 显然它不能在那个时候锁定 fd 表,所以你会陷入 EMFILE 和 EINTR 错误都发生的混乱......跨度> -
库文档说操作不能被中断,并且它没有将 EINTR 列为可能的错误。大概它的实现方式与
close不同。 -
如果您收到
EINTR,您可以重试dup2呼叫。所以在某些方面它不是一场灾难...... -
@teppic: atomic 在这里不是问题。 atomic 的意思是:要么成功,要么失败。它可能会失败。如果它确实失败了,也没有造成任何伤害。 (例如:关闭文件,但不复制新的 fd)
标签: linux posix freebsd language-lawyer file-descriptor