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

JAN*_*JAN 79 c linux operating-system system-calls

我想了解使用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).  
Run Code Online (Sandbox Code Playgroud)

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

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

我会很感激,如果你能解释给我,其中一个例子dup2/ dup是必要的.

谢谢

Dee*_*ght 41

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

Dup允许shell实现如下命令:

ls existing-file non-existing-file > tmp1  2>&1
Run Code Online (Sandbox Code Playgroud)

2>&1告诉shell给命令一个文件描述符2,它是描述符1的副本.(即stderr&stdout指向同一个fd).
现在,调用错误消息LS不存在的文件和正确的输出LS现有的文件中显示TMP1文件.

以下示例代码运行程序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]);
}
Run Code Online (Sandbox Code Playgroud)

子进程将读取结束重复到文件描述符0,关闭文件描述符p和exec wc.当wc从其标准输入读取时,它从管道读取.
这就是使用dup实现管道的方法,以及现在你使用管道来构建其他东西,这就是系统调用的美妙之处,你使用已经存在的工具构建一个接一个的东西,这些工具是使用工具构建的其他东西等等.最后系统调用是你在内核中获得的最基本的工具

干杯:)

  • 您的示例程序*似乎*有错误; 你正在调用`dup(p [STDIN])`然后扔掉结果.你的意思是使用`dup2(p [STDIN],0)`? (2认同)

R..*_*R.. 17

复制文件描述符的另一个原因是使用它fdopen.fclose关闭传递给的文件描述符fdopen,因此如果您不希望关闭原始文件描述符,则必须先复制它dup.

  • 你误解了我的回答.关键是你可能希望在将fd传递给`fdopen`之前'复制'fd,因为`fclose`将关闭它. (2认同)
  • 要点是 fdopen() 将 fd 的所有权“移动”到“FILE”,而不是“复制”它。这是用户应该注意的事情。除了“FILE”对象之外,还需要保留可用的“fd”句柄的消费者必须复制“fd”。就这样。 (2认同)
  • @ConradMeyer:是的,这是一个非常好的表达方式,请注意,一旦将所有权移至“FILE”,就没有任何操作可以将所有权从“FILE”中“移走”。 (2认同)