有人可以解释C中的dup()吗?
我知道dup,dup2,dup3“ 创建文件描述符oldfd的副本 ”(来自手册页)。 但是我无法消化它。
据我所知,文件描述符只是用于跟踪文件位置及其方向(输入/输出)的数字。 是不是更容易
fd=fd2;
每当我们想要复制文件描述符?
还有别的……
dup()使用编号最小的未使用描述符作为新描述符。
这是否意味着它还可以作为值stdin , stdout或stderr,如果我们假设我们有close() –其中一个?
只是想在尝试一下之后回答第二个问题。
答案是肯定的 。 如果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
没有。
关于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)的任何东西,神奇地进入“文件”。
假设你正在编写一个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将是一种浪费。
看到这个页面 ,stdout可以别名为dup(1)
…
只是关于“ 重复标准输出 ”的提示。
在一些Unix系统上(但不是GNU / Linux)
fd = open("/dev/fd/1", O_WRONLY);
它相当于:
fd = dup(1);
例:
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()
我已经关闭的文件描述符?
我怀疑你是否用显示的结果进行了上述实验,因为那不符合标准 – 参见 dup :
如果出现以下情况, dup ()函数将失败:
[EBADF] fildes参数不是有效的打开文件描述符。
因此,在显示的代码序列之后, newfd
必须不是1
,而是-1
,而errno
EBADF
。
dup()和dup2()系统调用
•dup()系统调用复制打开的文件描述符并返回新的文件描述符。
•新文件描述符具有与原始文件描述符相同的以下属性:1。引用相同的打开文件或管道。 2.具有相同的文件指针 – 也就是说,两个文件描述符共享一个文件指针。 3.具有相同的访问模式,无论是读,写还是读和写。
•dup()保证返回具有可用的最小整数值的文件描述符。这是因为返回可用的最低未使用文件描述符,该进程完成I / O重定向。
int dup(file_descriptor)
int dup2(file_descriptor1,file_descriptor2)