2011-10-22 26 views
17

我知道dup,dup2,dup3“”(从手册页)创建文件描述符oldfd的副本。但是我无法消化它。有人可以解释C中的dup()吗?

因为我知道文件描述符只是号码来跟踪文件位置及其方向(输入/输出)。难道这不是更容易

fd=fd2; 

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

而且别的东西..

DUP()使用新的描述符的编号最小的未使用的描述符。

这是否意味着它也可以采取为价值标准输入标准输出标准错误如果我们假定我们有close()方法 -ed其中的一个?

+3

对于你需要记住的是,内核保持数轨迹的第一个问题打开文件句柄。 'dup'是你告诉内核你想让它跟踪另一个文件句柄(指同一个文件)直到你关闭它的方式。 – user786653

回答

12

只是试图回应自己在第二个问题后试验了一下。

答案是YES。如果标准输入,标准输出或标准错误都关闭,那么您制作的文件描述符可以取值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

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

+0

根据定义,dup()为新描述符使用编号最小的未使用描述符。当你关闭一个文件描述符时,这意味着它可以使用。 –

2

看到这个page,标准输出可以别名为dup(1) ...

+0

+1。真棒链接 –

5

假设你正在写一个shell程序和要重定向stdin和stdout中要运行的程序。它可能是这个样子:

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

你为什么要究其原因:

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()可以被替换要做到这一点,你要报告错误标准输出(或标准错误),所以你不能关闭他们,并在子进程中打开一个新的文件。其次,如果open()调用返回错误,那么执行fork会很浪费。

9

文件描述符比数字多一点。它也带有各种半隐藏状态(无论是否打开,它引用哪个文件描述,还有一些标志)。 dup重复此信息,因此您可以独立地关闭这两个描述符。 fd=fd2没有。

+1

这个。 “数字”是内核维护的数据结构的索引。函数的'dup'族克隆了该数据结构中节点的状态,并将索引交给新节点。 – dmckee

+3

@dmckee:“内核”和“索引”是实现细节。有一些数据与“数字”相关联,不能由程序直接操作,并且由'dup()'克隆。这就是程序员需要知道的全部内容。顺便说一下,它不是一个非常有趣的数据,它只是一对标志和一个非常有趣的数据(打开的文件描述)的索引,而不是由'dup()'克隆的。 –

5

有关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(标准输出)后,奇迹般地进入“文件”。

+0

假设(不是无理)文件描述符0当前是打开的。如果没有'dup2()'(或'dup3()',支持重定向如'200> somefile'是非常不方便的,但这是系统的最新增加)。 –

0

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

在一些Unix系统(而不是GNU/Linux)的

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

它相当于:

fd = dup(1);