前面的例子中,子进程可以直接共享父进程的文件描述符。但是如果子进程调用exec函数执行另一个应用程序时,就不能再共享了。
这种情况下可以将子进程中的文件描述符重定向到标准输入,当新执行的程序从标准输入获取数据时实际上是从父进程中获取输入数据。
dup和dup2函数提供了复制文件描述符的功能。
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup和dup2能够复制文件描述符。dup 和dup2都是返回新的描述符。或者返回-1并设置 errno变量。新老描述符共享文件的偏移量(位置)、标志和锁,但是不共享close-on-exec标志。
---------------------------------------------------------------------------------------------------------------------
int dup(int oldfd); 拷贝fd,返回当前系统最小且没有被使用的fd。
int dup2(int oldfd,int newfd); dup2可以让用户指定返回的文件描述符的值,dup2可以指定拷贝后的newfd,原先的newfd会被关闭 。
int n_fd = dup2(fd, STDOUT_FILENO);
将STDOUT_FILENO重定向到fd,即文件描述符STDOUT_FILENO复制了文件描述符fd,共享fd对应的文件对象。此时任何目标为STDOUT_FILENO的I/O操作,如printf()等数据都会流入fd3对应的文件。
----------------------------------------------------------------------------------------------------------
dup跟dup2的使用对比:
pid=fork()
if(0 == pid)
{
...............
close(1);
dup(fd[1])
...................
}
pid=fork()
if(0 == pid)
{
.......................
dup2(fd[1], 1])
..............................
}
dup2系统调用将close操作和文件描述符拷贝操作集成在同一个函数里,而且它保证操作具有原子性。