我知道 dup, dup2, dup3 “创建文件描述符 oldfd 的副本”(来自手册页)。然而我无法消化它。
据我所知,文件描述符只是跟踪文件位置及其方向(输入/输出)的数字。这不是更容易吗
fd=fd2;
每当我们想要复制文件描述符时?
还有别的..
dup() 为新描述符使用编号最小的未使用描述符。
这是否意味着如果我们假设我们有close() -ed 其中之一,它也可以作为值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
才不是。
假设您正在编写一个 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 将是一种浪费。
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)的任何内容都会神奇地进入“文件”。
例子:
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
。
看到这个页面,标准输出可以别名为dup(1)
...
只是关于“复制标准输出”的提示。
在某些 Unix 系统上(但不是 GNU/Linux)
fd = open("/dev/fd/1", O_WRONLY);
它相当于:
fd = dup(1);
dup() 和 dup2() 系统调用
• dup() 系统调用复制打开的文件描述符并返回新的文件描述符。
• 新文件描述符与原始文件描述符具有以下共同属性: 1. 指向同一个打开的文件或管道。2. 具有相同的文件指针——即两个文件描述符共享一个文件指针。3.具有相同的访问方式,无论是读、写,还是读写。
• dup() 保证返回具有最低可用整数值的文件描述符。正是由于这种返回可用的最低未使用文件描述符的特性,进程完成了I/O 重定向。
int dup(文件描述符)
int dup2(file_descriptor1,file_descriptor2)