C语言 有人能解释一下 C 中的 dup() 是做什么的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7861611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can someone explain what dup() in C does?
提问by Pithikos
I know that dup, dup2, dup3 "create a copy of the file descriptor oldfd"(from man pages). However I can't digest it.
我知道 dup、dup2、dup3“创建文件描述符 oldfd 的副本”(来自手册页)。然而我消化不了。
As I know file descriptors are just numbersto keep track of file locations and their direction(input/output). Wouldn't it be easier to just
据我所知文件描述符只是数字来跟踪文件的位置和它们的方向(输入/输出)。只是不是更容易
fd=fd2;
Whenever we want to duplicate a file descriptor?
每当我们想要复制文件描述符时?
And something else..
还有其他东西..
dup() uses the lowest-numbered unused descriptor for the new descriptor.
dup() 使用编号最小的未使用描述符作为新描述符。
Does that mean that it can also take as value stdin, stdoutor stderrif we assume that we have close()-ed one of those?
这是否意味着如果我们假设我们有close() 中的一个,它也可以作为值stdin、stdout或stderr?
采纳答案by Pithikos
Just wanted to respond to myself on the second question after experimenting a bit.
只是想在尝试一下后就第二个问题回答自己。
The answer is YES. A file descriptor that you make can take a value 0, 1, 2 if stdin, stdout or stderr are closed.
答案是肯定的。如果 stdin、stdout 或 stderr 关闭,您创建的文件描述符可以取值为 0、1、2。
Example:
例子:
close(1); //closing stdout
newfd=dup(1); //newfd takes value of least available fd number
Where this happens to file descriptors:
文件描述符发生这种情况的地方:
0 stdin .--------------. 0 stdin .--------------. 0 stdin
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd
2 stderr '--------------' '--------------' 2 stderr
回答by n. 'pronouns' m.
A file descriptor is a bit more than a number. It also carries various semi-hidden state with it (whether it's open or not, to which file description it refers, and also some flags). dupduplicates this information, so you can e.g. close the two descriptors independently. fd=fd2does not.
文件描述符不仅仅是一个数字。它还带有各种半隐藏状态(无论它是否打开,它所引用的文件描述,以及一些标志)。dup复制此信息,因此您可以例如独立关闭两个描述符。fd=fd2才不是。
回答by Richard Pennington
Let's say you're writing a shell program and you want to redirect stdin and stdout in a program you want to run. It could look something like this:
假设您正在编写一个 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() is a little more convenient way to do it the close() dup() can be replaced by:
dup2() 是一种更方便的方法,可以将 close() dup() 替换为:
dup2(fdin, 0);
dup2(fdout, 1);
The reason why you want to do this is that you want to report errors to stdout (or stderr) so you can't just close them and open a new file in the child process. Secondly, it would be a waste to do the fork if either open() call returned an error.
你要这样做的原因是你想向 stdout(或 stderr)报告错误,所以你不能只是关闭它们并在子进程中打开一个新文件。其次,如果 open() 调用返回错误,则执行 fork 将是一种浪费。
回答by SzG
The single most important thing about dup() is it returns the smallest integer available for a new file descriptor. That's the basis of redirection:
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 */
After this anything written to file descriptor 1 (stdout), magically goes into "file".
在写入文件描述符 1 (stdout) 的任何内容之后,神奇地进入“文件”。
回答by b3h3m0th
Just a tip about "duplicating standard output".
只是关于“复制标准输出”的提示。
On some Unix Systems (but not GNU/Linux)
在某些 Unix 系统上(但不是 GNU/Linux)
fd = open("/dev/fd/1", O_WRONLY);
it is equivalent to:
它相当于:
fd = dup(1);
回答by Armali
Example:
close(1); //closing stdout newfd=dup(1); //newfd takes value of least available fd numberWhere this happens to file descriptors:
0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr '--------------' '--------------' 2 stderrA question arose again: How can I
dup()a file descriptor that I already closed?
例子:
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()关闭我已经关闭的文件描述符?
I doubt that you conducted the above experiment with the shown result, because that would not be standard-conforming - cf. dup:
我怀疑您是否使用显示的结果进行了上述实验,因为这不符合标准 - 参见。重复:
The dup() function shall fail if:
[EBADF] The fildesargument is not a valid open file descriptor.
如果出现以下情况,dup() 函数将失败:
[EBADF] 该菲尔德斯参数不是有效的打开文件描述符。
So, after the shown code sequence, newfdmust be not 1, but rather -1, and errnoEBADF.
因此,在显示的代码序列之后,newfd必须不是1,而是-1, 和errnoEBADF。
回答by Mahendra suthar
dup() and dup2() system call
dup() 和 dup2() 系统调用
?The dup() system call duplicates an open file descriptor and returns the new file descriptor.
? dup() 系统调用复制一个打开的文件描述符并返回新的文件描述符。
?The new file descriptor has the following properties in common with the original file descriptor: 1. refers to the same open file or pipe. 2. has the same file pointer -- that is, both file descriptors share one file pointer. 3. has the same access mode, whether read, write, or read and write.
?新的文件描述符与原文件描述符有以下共同点: 1. 指的是同一个打开的文件或管道。2. 具有相同的文件指针——也就是说,两个文件描述符共享一个文件指针。3.具有相同的访问方式,无论是读、写,还是读写。
? dup() is guaranteed to return a file descriptor with the lowest integer value available.It is because of this feature of returning the lowest unused file descriptor available that processes accomplish I/O redirection.
? dup() 保证返回一个可用整数值最低的文件描述符。正是由于这个返回最低可用文件描述符的特性,进程完成了 I/O 重定向。
int dup(file_descriptor)
int dup(file_descriptor)
int dup2(file_descriptor1, file_descriptor2)
int dup2(file_descriptor1, file_descriptor2)

