有人可以解释C中的dup()吗?

时间:2011-10-22 18:12:53

标签: c pipe dup2 dup

我知道dup,dup2,dup3“创建文件描述符oldfd 的副本”(来自手册页)。但是我无法消化它。

据我所知,文件描述符只是数字来跟踪文件位置及其方向(输入/输出)。只是

会不会更容易
fd=fd2;

每当我们想要复制文件描述符时?

还有别的......

  

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

这是否意味着如果我们假设我们关闭它,它也可以取值 stdin stdout stderr - 其中一个?

8 个答案:

答案 0 :(得分:15)

在尝试了一下之后,我想回答第二个问题。

答案是。如果stdin,stdout或stderr关闭,则您创建的文件描述符可以取值0,1,2。

示例:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

文件描述符发生的地方:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr

答案 1 :(得分:11)

文件描述符不仅仅是一个数字。它还带有各种半隐藏状态(无论是否打开,它所引用的文件描述,以及一些标志)。 dup重复此信息,因此您可以例如独立关闭两个描述符。 fd=fd2没有。

答案 2 :(得分:6)

关于dup()最重要的一点是它返回可用于新文件描述符的最小整数。这是重定向的基础:

int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */

在此之后写入文件描述符1(stdout)的任何东西,神奇地进入“文件”。

答案 3 :(得分:5)

假设你正在编写一个shell程序,并且想要在要运行的程序中重定向stdin和stdout。它可能看起来像这样:

fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
    close(0);
    dup(fdin);
    close(fdin);
    close(1);
    dup(fdout);
    close(fdout);
    execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...

dup2()是一种更方便的方法,close()dup()可以替换为:

dup2(fdin, 0);
dup2(fdout, 1);

你想要这样做的原因是你想向stdout(或stderr)报告错误,所以你不能只关闭它们并在子进程中打开一个新文件。其次,如果open()调用返回错误,那么执行fork将是一种浪费。

答案 4 :(得分:2)

请参阅此page,stdout可以别名为dup(1) ...

答案 5 :(得分:0)

关于“重复标准输出”的提示。

在某些Unix系统上(但不是GNU / Linux)

el.location, el.size and screen size information

相当于:

fd = open("/dev/fd/1", O_WRONLY);

答案 6 :(得分:0)

  

示例:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr
     

文件描述符发生的地方:

dup()
     

又出现了一个问题:我如何newfd我已经关闭的文件描述符?

我怀疑你是否按照所示结果进行了上述实验,因为这不符合标准 - 参见Enabling Progress and Cancellation in Async APIs

如果符合以下情况, dup ()函数将失败:

[EBADF]
fildes 参数不是有效的打开文件描述符。

因此,在显示的代码序列之后,1必须不是-1,而是errnoEBADF System.Reflection.GetType().GetProperties()

答案 7 :(得分:0)

dup()和dup2()系统调用

••dup()系统调用复制一个打开的文件描述符并返回新文件 描述符。

•新的文件描述符具有与以下相同的属性 原本的 文件描述符: 1.指相同的打开文件或管道。 2.具有相同的文件指针-也就是说,两个文件描述符共享一个文件指针。 3.具有相同的访问模式,无论是读取,写入还是读取和写入。

•dup()保证返回的文件描述符具有最小的可用整数值。这是因为此功能返回了可用的最低的未使用文件描述符,从而使进程完成了I / O重定向。

int dup(file_descriptor)

int dup2(file_descriptor1,file_descriptor2)