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

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

据我所知,文件描述符只是用于跟踪文件位置及其方向(输入/输出)的数字。 是不是更容易

fd=fd2; 

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

还有别的……

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

这是否意味着它还可以作为值stdinstdoutstderr,如果我们假设我们有close() –其中一个?

只是想在尝试一下之后回答第二个问题。

答案是肯定的 。 如果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 

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

关于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)的任何东西,神奇地进入“文件”。

假设你正在编写一个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将是一种浪费。

看到这个页面 ,stdout可以别名为dup(1)

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

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

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

它相当于:

 fd = dup(1); 

例:

 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 

一个问题再次出现:我如何dup()我已经关闭的文件描述符?

我怀疑你是否用显示的结果进行了上述实验,因为那不符合标准 – 参见 dup :

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

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

因此,在显示的代码序列之后, newfd必须不是1 ,而是-1 ,而errno EBADF

dup()和dup2()系统调用

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

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

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

int dup(file_descriptor)

int dup2(file_descriptor1,file_descriptor2)