今天看书遇到了两个函数dup, dup2
半天才弄明白它们干了些什么, 现分享如下:
当我们用open()打开一个文件时, 会得到一个文件描述符, 这个文件描述符会指向一个file结构体,最终对文件的操 作需要借助这个结构体
文件描述符从0开始,默认0为stdin,1为stdout,2为stderr
dup和dup2的百度百科给出的解释是复制一个现存的文件描述符
(为什么觉得不是这样,文件描述符只是一个int数值,复制不是应该跟它相等?可是明显不是。复制指向的file结构 体?可是结构体dup进行后还是只有一个, 只是有两个文件描述符指向这同一个file结构体)
下面看具体的函数:
int dup(int oldfd);
dup进行的操作是在所有未使用的文件描述符中取出最小的一个,并让这个文件描述符也指向oldfd指向的file结构体,这样返回的新的文件描述符newfd可以用来操作oldfd指向的文件。
今天产生的疑问也就是源于这段不完整代码
pipe(fd); //定义为int fd[2];
childpid = fork();
if(childpid == 0)
{
/* 关闭子进程的文件句柄 0(stdin) */
close(0);
/* 将管道的读句柄定义到 stdin */
dup(fd[0]);
execlp(“sort”,“sort”, NULL);
}
现在明白 这里dup进行的操作是在所有未使用的文件描述符中取出最小的被close()关闭的stdin(即0),并让stdin也指向fd[0]指向的file结构体(在这里是管道的读出端),这样用在子进程中用stdin读出的实际是fd[0]指向的管道读出端。 这样在子进程里可以从标准输入读出从父进程管道传来的数据。(实现了父子进程通信)
int dup2(int newfd, int oldfd);
dup2跟dup很相似, 它将默认的选取最小文件描述符这项操作改成了自己选定文件描述符, 当选定的newfd已经打开时,即已经跟一个file结构体相连时, 就断开它们的连接, 使这个文件描述符指向oldfd指向的file结构体 (当newfd与oldfd相等, 返回newfd)
总结:
dup和dup2为同一文件表项添加了一个额外的文件描述符, 让其可以代替另一个文件描述符工作, 在需要的时候提供便利。
参考:http://blog.donews.com/mutecat/archive/2007/09/20/1212178.aspx
http://baike.baidu.com/view/656625.htm
http://www.cnblogs.com/sdphome/archive/2011/04/30/2033381.html