码迷,mamicode.com
首页 > 系统相关 > 详细

linux文件系统,dup2等

时间:2014-07-31 20:48:07      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:文件系统   linux   

在说linux的文件前,先看看linux的文件系统。虽然实现细节有差异,但文件系统的大致组织形式如下图所示:
bubuko.com,布布扣
局部放大:
bubuko.com,布布扣
由以上两个图可见,对每一个文件都有一个i节点与之对应,这是linux文件系统把文件和文件信息分别抽象出来的结果,文件信息保存在i节点上(i节点长度固定,内容包括文件类型、文件存取许可权位、文件长度和指向该文件所占用的数据块的指针等等,但不包括文件名),可通过系统调用stat(2)、fstat(2)、lstat(2)获取。i节点数量太多,为提高查找效率,内核有时通过一张hash来索引。而文件则保存在数据块区。

由上图还可以看出,可以有多个目录项指向同一个i节点。实质上是每个i节点有一个连接计数(硬连接),只有在指向i节点的目录项数减为0时文件才被删除,相应数据块释放。硬连接的作用是允许一个文件拥有多个有效路径名。
BTW:
与之相对的另一种符号连接(Symbolic Link),也叫软连接。软连接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。它有自己的i节点,该i节点中的文件类型是S_IFLNK,于是系统知道这是一个符号连接。当我们删除了源文件后,链接文件不能独立存在,虽然仍保留文件名。

另外,在linux里,目录也是一种文件,它通常只包含文件名列表和i节点的位置信息,如图,i节点1267指向的目录创建了子目录testdir(inode2549):
bubuko.com,布布扣
由图易见,任何一个目录,连接计数至少为2

接着,看看内核处理I/O的数据结构:
bubuko.com,布布扣
进程表项存在在每一个进程里,文件表项是为每一个打开的文件维护的,其中的文件状态标志包括读、写、增写、同步、非阻塞等,v节点可理解为上文的i节点,不同系统实现细节稍有差异。
两个独立进程分别打开同一文件时(同一进程open两次也与之类似):
bubuko.com,布布扣
注意fork的差异,fork之后,父、子进程对于每一个打开的文件描述符共享同一个文件表项

文件描述符的复制:
#include <unistd.h>
    int dup( int oldfd );
    int dup2( int oldfd, int newfd )
由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。如果newfd已经打开,则先将其关闭。如若oldfd等于newfd,则返回newfd而不关闭它。但他们两个都是原子操作。
如,执行dup(4,1)后,内核数据结构如下所示:
bubuko.com,布布扣
因为两个描述符指向同一文件表项,所以它们共享同一文件状态标志(读、写、添写等)以及同一当前文件位移量。

如果想在复制后恢复,通常的做法是用一个save_fd来备份newfd。
比如:
save_fd = dup(STDOUT_FILENO);
dup2(fd, STDOUT_FILENO);
close(fd);
write(STDOUT_FILENO, msg, strlen(msg));
dup2(save_fd, STDOUT_FILENO);
write(STDOUT_FILENO, msg, strlen(msg));
close(save_fd);
过程如图:
bubuko.com,布布扣
注:
第3幅图,要执行dup2(fd, 1);,文件描述符1原本指向tty,现在要指向新的文件somefile,就把原来的关闭了,但是tty这个文件原本有两个引用计数,还有文件描述符save_fd也指向它,所以只是将引用计数减1,并不真的关闭文件。
第5幅图,要执行dup2(save_fd, 1);,文件描述符1原本指向somefile,现在要指向新的文件tty,就把原来的关闭了,somefile原本只有一个引用计数,所以这次减到0,是真的关闭了。






linux文件系统,dup2等,布布扣,bubuko.com

linux文件系统,dup2等

标签:文件系统   linux   

原文地址:http://blog.csdn.net/simon_xia_uestc/article/details/38054617

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!