我正在尝试理解dup2
和dup
的用法。
在手册页中:
描述
dup
和dup2
创建文件描述符oldfd
的副本,成功返回dup
或dup2
后,新旧描述符可以互换使用,它们共享锁、文件位置指针和标志;例如,如果通过在描述符之一上使用lseek
来修改文件位置,则对于另一个描述符,位置也改变。
这两个描述符不共享close-on-exec标志,但是,dup
将编号最小的未使用描述符用作新描述符。dup2
使newfd
成为oldfd
的副本,如有必要,先关闭newfd
。
返回值
dup
和dup2
返回新的描述符,如果发生错误,则返回-1(在这种情况下,errno
被适当地设置)。
为什么我需要那个系统调用?复制文件描述符有什么用?如果我有文件描述符,为什么我要复制它?如果你能解释并给我一个需要dup2
/dup
的例子,我会很感激。
4条答案
按热度按时间p4tfgftt1#
dup系统调用复制一个现有的文件描述符,返回一个引用同一底层I/O对象的新文件描述符。
Dup允许shell实现如下命令:
2〉&1告诉shell给予命令一个文件描述符2,它是描述符1的副本(例如stderr和stdout指向相同的fd)。
现在,在 * non-existing file* 上调用 ls 的错误消息和在 existing file 上调用 ls 的正确输出显示在 * tmp 1 * 文件中。
下面的示例代码运行程序wc,标准输入连接到管道的读取端。
子进程将read end复制到文件描述符0上,关闭p中的文件描述符,并执行wc。当wc从其标准输入读取时,它从管道读取。
这就是使用dup实现管道的方式,现在使用dup可以构建其他东西,这就是系统调用的美妙之处,您可以使用已有的工具构建一个又一个东西,这些工具反过来又是使用其他东西构建的,依此类推。最后,系统调用是您在内核中获得的最基本的工具
干杯:)
r1zk6ea12#
复制文件描述符的另一个原因是将其与
fdopen
一起使用。fclose
会关闭传递给fdopen
的文件描述符,因此如果不希望原始文件描述符关闭,则必须首先使用dup
复制它。bjp0bcyl3#
dup用于能够重定向来自进程的输出。
例如,如果您想保存一个进程的输出,您可以复制该输出(fd=1),将复制的fd重定向到一个文件,然后派生并执行该进程,当该进程完成时,再次将保存的fd重定向到输出。
wmomyfyw4#
请注意与dup/dup 2相关的一些要点
dup/dup 2-从技术上讲,其目的是通过不同的句柄在单个进程内共享一个文件表条目。(如果我们正在派生,则描述符默认在子进程中复制,并且文件表条目也被共享)。
这意味着我们可以使用dup/dup 2函数为一个打开文件表条目创建多个具有 * 可能不同属性 * 的文件描述符。
(尽管目前似乎只有FD_CLOEXEC标志是文件描述符的唯一属性)。
http://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html
区别是(最后一个)-除了dup 2和fcntl之间的一些errno值之外,close后面跟fcntl可能会引发争用条件,因为涉及到两个函数调用。
可从http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html查看详细信息
使用示例-
在shell中实现作业控制时,有一个有趣的示例,其中可以看到dup/dup 2的使用。请参见下面的链接
http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs