dup(2) - Linux man page

名称

dup, dup2, dup3 - 复制文件描述符

概要

#include <unistd.h>
int dup(int oldfd);int dup2(int oldfd, int newfd);
#define _GNU_SOURCE             /* See feature_test_macros(7) */#include
<fcntl.h>              /* Obtain O_* constant definitions */#include <unistd.h>
int dup3(int oldfd, int newfd, int flags);

描述

这些系统调用会创建文件描述符 oldfd 的副本。

dup() 使用最低编号的未使用的描述符作为新的描述符。

dup2() 使 newfd 成为 oldfd 的副本,如果需要则先关闭 newfd,但请注意以下几点

*
如果 oldfd 不是有效的文件描述符,则调用失败,并且 newfd 不会被关闭。
*
如果 oldfd 是有效的文件描述符,并且 newfdoldfd 具有相同的值,则 dup2() 什么也不做,并返回 newfd

在这些系统调用之一成功返回后,旧的和新的文件描述符可以互换使用。它们引用相同的打开文件描述符(参见 open(2)),因此共享文件偏移量和文件状态标志;例如,如果通过使用 lseek(2) 在其中一个描述符上修改文件偏移量,则另一个描述符的文件偏移量也会更改。

这两个描述符不共享文件描述符标志(close-on-exec 标志)。副本描述符的 close-on-exec 标志 (FD_CLOEXEC; 参见 fcntl(2)) 是关闭的。

dup3() 与 dup2() 相同,除了

*
调用者可以通过在 flags 中指定 O_CLOEXEC 来强制为新的文件描述符设置 close-on-exec 标志。有关为什么这可能很有用的原因,请参见 open(2) 中对相同标志的描述。
*
如果 oldfd 等于 newfd,则 dup3() 将以错误 EINVAL 失败。

返回值

成功时,这些系统调用返回新的描述符。发生错误时,返回 -1,并且 errno 被设置为适当的值。

错误

EBADF
oldfd 不是打开的文件描述符,或者 newfd 超出了文件描述符的允许范围。
EBUSY
(仅限 Linux) 这可能由 dup2() 或 dup3() 在与 open(2)dup() 发生竞争条件时返回。
EINTR
dup2() 或 dup3() 调用被信号中断;参见 signal(7)
EINVAL
(dup3()) flags 包含无效值。或者,oldfd 等于 newfd
EMFILE
进程已经打开了最大数量的文件描述符并尝试打开一个新的文件描述符。

版本

dup3() 在 Linux 2.6.27 版本中添加;glibc 支持从版本 2.9 开始可用。

符合

dup(), dup2(): SVr4, 4.3BSD, POSIX.1-2001。

dup3() 是 Linux 特有的。

说明

dup2() 返回的错误与当 newfd 超出范围时 fcntl(..., F_DUPFD, ...) 返回的错误不同。在某些系统上,dup2() 也会像 F_DUPFD 一样有时返回 EINVAL

如果 newfd 已打开,任何在 close(2) 时会报告的错误都将丢失。谨慎的程序员不会在不先关闭 newfd 的情况下使用 dup2() 或 dup3()。

参见

close(2), fcntl(2), open(2)

引用自

epoll(7), explain(1), explain(3), explain_dup(3), explain_dup_or_die(3), flock(2), getdtablesize(2), getdtablesize(3), getrlimit(2), io_passfd(3), ksh(1), ksh93(1), lam_rfposix(2), mksh(1), perlfunc(1), perlopentut(1), pipe(7), unix(7), xs(1)