25

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

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

fd=fd2;

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

还有别的..

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

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

4

8 回答 8

20

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

答案是肯定的。如果标准输入、标准输出或标准错误已关闭,您创建的文件描述符可以取值 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
于 2011-10-24T14:49:28.523 回答
14

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

于 2011-10-22T18:54:37.147 回答
7

假设您正在编写一个 shell 程序,并且您想要在您想要运行的程序中重定向标准输入和标准输出。它可能看起来像这样:

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 将是一种浪费。

于 2011-10-22T18:30:27.773 回答
7

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)的任何内容都会神奇地进入“文件”。

于 2013-08-03T08:04:31.447 回答
3

例子:

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()获得已经关闭的文件描述符?

我怀疑您是否使用显示的结果进行了上述实验,因为那不符合标准 - cf。重复

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

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

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

于 2018-05-28T09:10:55.100 回答
2

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

于 2011-10-22T18:19:19.787 回答
1

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

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

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

它相当于:

fd = dup(1);
于 2016-10-03T17:52:12.583 回答
0

dup() 和 dup2() 系统调用

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

• 新文件描述符与原始文件描述符具有以下共同属性: 1. 指向同一个打开的文件或管道。2. 具有相同的文件指针——即两个文件描述符共享一个文件指针。3.具有相同的访问方式,无论是读、写,还是读写。

• dup() 保证返回具有最低可用整数值的文件描述符。正是由于这种返回可用的最低未使用文件描述符的特性,进程完成了I/O 重定向。

int dup(文件描述符)

int dup2(file_descriptor1,file_descriptor2)

于 2018-10-22T09:35:05.533 回答