我知道dup,dup2,dup3“创建文件描述符oldfd 的副本”(来自手册页)。但是我无法消化它。
据我所知,文件描述符只是数字来跟踪文件位置及其方向(输入/输出)。只是
会不会更容易fd=fd2;
每当我们想要复制文件描述符时?
还有别的......
dup()使用编号最小的未使用描述符作为新描述符。
这是否意味着如果我们假设我们关闭它,它也可以取值 stdin , stdout 或 stderr ) - 其中一个?
答案 0 :(得分:15)
在尝试了一下之后,我想回答第二个问题。
答案是是。如果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
答案 1 :(得分:11)
文件描述符不仅仅是一个数字。它还带有各种半隐藏状态(无论是否打开,它所引用的文件描述,以及一些标志)。 dup
重复此信息,因此您可以例如独立关闭两个描述符。 fd=fd2
没有。
答案 2 :(得分:6)
关于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)的任何东西,神奇地进入“文件”。
答案 3 :(得分:5)
假设你正在编写一个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将是一种浪费。
答案 4 :(得分:2)
请参阅此page,stdout可以别名为dup(1)
...
答案 5 :(得分:0)
关于“重复标准输出”的提示。
在某些Unix系统上(但不是GNU / Linux)
el.location, el.size and screen size information
相当于:
fd = open("/dev/fd/1", O_WRONLY);
答案 6 :(得分:0)
示例:
0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr '--------------' '--------------' 2 stderr
文件描述符发生的地方:
dup()
又出现了一个问题:我如何
newfd
我已经关闭的文件描述符?
我怀疑你是否按照所示结果进行了上述实验,因为这不符合标准 - 参见Enabling Progress and Cancellation in Async APIs:
如果符合以下情况, dup ()函数将失败:
[EBADF] fildes 参数不是有效的打开文件描述符。
因此,在显示的代码序列之后,1
必须不是-1
,而是errno
和EBADF
System.Reflection.GetType().GetProperties()
。
答案 7 :(得分:0)
dup()和dup2()系统调用
••dup()系统调用复制一个打开的文件描述符并返回新文件 描述符。
•新的文件描述符具有与以下相同的属性 原本的 文件描述符: 1.指相同的打开文件或管道。 2.具有相同的文件指针-也就是说,两个文件描述符共享一个文件指针。 3.具有相同的访问模式,无论是读取,写入还是读取和写入。
•dup()保证返回的文件描述符具有最小的可用整数值。这是因为此功能返回了可用的最低的未使用文件描述符,从而使进程完成了I / O重定向。
int dup(file_descriptor)
int dup2(file_descriptor1,file_descriptor2)