一尘不染

dup2 / dup-为什么我需要复制一个文件描述符?

linux

我想了解使用dup2dup

从手册页:

DESCRIPTION

dup and dup2 create a copy of the file descriptor oldfd.
After successful return of dup or dup2, the old and new descriptors may
be used interchangeably. They share locks, file position pointers and
flags; for example, if the file position is modified by using lseek on
one of the descriptors, the position is also changed for the other.

The two descriptors do not share the close-on-exec flag, however.

dup uses the lowest-numbered unused descriptor for the new descriptor.

dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.

RETURN VALUE

dup and dup2 return the new descriptor, or -1 if an error occurred 
(in which case, errno is set appropriately).

为什么我需要该系统调用?复制文件描述符有什么用?

如果我有文件描述符,为什么要复制它?

如果您能解释一下并举一个需要dup2/ 的示例,我们将不胜感激dup

谢谢


阅读 416

收藏
2020-06-03

共1个答案

一尘不染

dup系统调用复制了一个现有的文件描述符,并返回了一个新的文件描述符,该描述符引用了相同的基础I / O对象。

Dup允许Shell执行以下命令:

ls existing-file non-existing-file > tmp1  2>&1

2>&1告诉外壳程序给命令一个文件描述符2,它是描述符1的副本(即stderr&stdout指向相同的fd)。
现在,在 tmp1 文件中显示了在 不存在的文件 上调用 ls 的错误消息以及在 现有文件 上的 ls 的正确输出。

以下示例代码使用标准输入连接到管道的读取端运行程序wc。

int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
    close(STDIN); //CHILD CLOSING stdin
    dup(p[STDIN]); // copies the fd of read end of pipe into its fd i.e 0 (STDIN)
    close(p[STDIN]);
    close(p[STDOUT]);
    exec("/bin/wc", argv);
} else {
    write(p[STDOUT], "hello world\n", 12);
    close(p[STDIN]);
    close(p[STDOUT]);
}

子进程将读取端复制到文件描述符0上,关闭p中的文件描述符,然后执行wc。当wc从其标准输入中读取时,它将从管道中读取。
这就是使用dup实现管道的方式,好吧,现在使用dup一次使用管道来构建其他东西,这就是系统调用的美,您使用已经存在的工具来构建另一件东西,这些工具又是使用等等。最后,系统调用是您在内核中获得的最基本的工具

干杯:)

2020-06-03