在了解dup用法之前,需要对linux的文件节点有一个认识。
内核有3个数据结构来表示进程打开的文件,dup是系统提供的一个API可以直接操作这三个数据结构之间的关系。
(1)每个进程在进程表当中都有一个记录项,记录项中包含一张表格,记录了所有当前进程打开的文件,可以将其想象成为一个key-value的映射关系,key为文件描述符fd,对于每个进程来说,fd从0开始向后排,value为指向文件表的一个指针。
(2)文件表是内核管理打开文件的一张表,内核为每个打开的文件维持了一个文件表,包含文件状态标识(read, write, append, nonblock)等,当前文件偏移量和一个指向v-node的指针
(3)v-node包含了文件类型和对此文件进行各种操作的函数指针,还有可能包含该文件的i-node。这些信息都是在打开文件时从硬盘读入内存的。
dup系列函数的本质实际上是对文件指针的复制,可以顺序生成文件描述符(fd),或者要求在指定描述符上复制文件指针(dup2)。上图事实上就是执行了 newfd = dup(1)以后的内核存储结构(假设下一个可用的文件描述符为3)。
#include <unistd.h> int dup(int fd); //复制fd对应的文件表指针,返回下一个可用的文件描述符 int dup2(int fd1, int fd2); //将fd2对应的文件表指针修改为fd1对应的文件表指针
现在有一个需求是将当前进程所有打印在屏幕上面的信息打印到一个指定的文件内,用dup2来实现就很容易了。
#include "apue.h" int main() { int fd = open("test.txt", O_RDWR); dup2(fd, STDOUT_FILENO); //将1对应的文件表指针修改为fd对应的文件表指针 //后面所有的printf操作都会将信息打印在 test.txt当中 return 0; }
原文地址:http://blog.csdn.net/tuantuanls/article/details/39157227