linux文件系统,dup2等

在说linux的文件前,先看看linux的文件系统。虽然实现细节有差异,但文件系统的大致组织形式如下图所示:

局部放大:

由以上两个图可见,对每一个文件都有一个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):

由图易见,任何一个目录,连接计数至少为2

接着,看看内核处理I/O的数据结构:

进程表项存在在每一个进程里,文件表项是为每一个打开的文件维护的,其中的文件状态标志包括读、写、增写、同步、非阻塞等,v节点可理解为上文的i节点,不同系统实现细节稍有差异。

两个独立进程分别打开同一文件时(同一进程open两次也与之类似):

注意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)后,内核数据结构如下所示:

因为两个描述符指向同一文件表项,所以它们共享同一文件状态标志(读、写、添写等)以及同一当前文件位移量。

如果想在复制后恢复,通常的做法是用一个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);

过程如图:

注:

第3幅图,要执行dup2(fd, 1);,文件描述符1原本指向tty,现在要指向新的文件somefile,就把原来的关闭了,但是tty这个文件原本有两个引用计数,还有文件描述符save_fd也指向它,所以只是将引用计数减1,并不真的关闭文件。

第5幅图,要执行dup2(save_fd, 1);,文件描述符1原本指向somefile,现在要指向新的文件tty,就把原来的关闭了,somefile原本只有一个引用计数,所以这次减到0,是真的关闭了。

linux文件系统,dup2等

时间: 2024-10-29 19:12:30

linux文件系统,dup2等的相关文章

Linux文件系统相关知识整理

1.      磁盘的物理结构 盘面:磁盘是由一叠盘面组成 磁头(Heads):每个磁头对应一个盘面,负责该盘面上的数据的读写 磁道(Track):每个盘面会围绕圆心划分出多个同心圆圈,每个圆圈叫做一个磁道 柱面(Cylinders):所有盘片上的同一位置的磁道组成的立体叫做一个柱面 扇区(Sector):以磁道为单位管理磁盘仍然太大,所以计算机前辈们又把每个磁道划分出了多个扇区 磁盘容量的大小一般和磁道的密集程度有关,扇区数一般是不变的 2.      磁盘I/O的过程 首先是磁头径向移动来寻

linux 文件系统笔记

文件格式: windows:PE linux:  ELF 文件系统: rootfs FHS:规定linux应该创建哪些目录 /下的目录结构: /boot: 系统启动相关的文件,如内核,initrd,以及 grub(bootloader) /dev :设备文件(例如:光盘,cdrom) 类型: 块设备:随机访问, 数据块 字符设备:线性访问, 以字节为单位 设备号:主设备号(major),次设备号(minor) /etc:  配置文件(绝大多数为纯文本格式) /home: 用户的家目录,默认为/h

【转】LINUX文件系统剖析

引自:http://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/   在文件系统方面,Linux? 可以算得上操作系统中的 "瑞士军刀".Linux 支持许多种文件系统,从日志型文件系统到集群文件系统和加密文件系统.对于使用标准的和比较奇特的文件系统以及开发文件系统来说,Linux 是极好的平台.本文讨论 Linux 内核中的虚拟文件系统(VFS,有时候称为虚拟文件系统交换器),然后介绍将文件系统连接在一起的主要结构.

Linux文件系统

文件系统与目录结构 文件系统 1.文件和目录被组织成一个单根倒置数结构 2.文件系统从根目录下开始,用"/"表示 3.根文件系统(rootfs):root filesystem 4.文件名称区分大小写 5.以.开头的文件为隐藏文件 6.路径分隔符:/ 7.文件的两类数据: 元数据(metadata)和 数据(data) 8.文件系统分层结构:LSB (Linux Standard Base) 9.FHS(Filesystem Hierarchy System) 文件名规则 1.文件名最

linux文件系统索引节点浅析

索引节点,Inode是Index Node的缩写,存储于文件系统上的任何文件都可以用索引节点来表示,所以也可以说索引节点是整个linux文件系统的基础.操作系统在读取硬盘的时候不是一个块一个块的来读取信息,因为这样做的话效率太低,文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者.文件的创建日期.文件的大小等等.这种储存文件元信息的区域就叫做inode,中文译名为"索引节点". 在Linux系统中,文件系统主要分为两部分,

嵌入式 Linux根文件系统移植(一)——Linux文件系统简介

嵌入式 Linux根文件系统移植(一)--Linux文件系统简介 本文对文件系统分析的代码来源于linux 2.6.35.7版本. 一.文件系统的体系结构 文件系统是对存储设备上的数据和元数据进行组织的机制,便于用户和操作系统的交互.Linux支持多种文件系统,文件系统接口实现为分层的体系结构,将用户接口层.文件系统实现和操作存储设备的驱动程序分隔开.Linux文件系统的体系结构如下: 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C库(glibc),为文件系统调用(打开.读取.

linux --&gt; 文件系统十问

文件系统十问 参考:http://djt.qq.com/article/view/620 关于Linux文件系统相关的问题: 1.机械磁盘随机读写时速度非常慢,操作系统是采用什么技巧来提高随机读写的性能的? 2.touch一个新的空文件占用磁盘空间吗? 占用的话占用多少? 3.新建一个空目录占用磁盘空间吗?占用多少?和新建一个文件相比,哪个占用的更大? 4.你知道文件名是记录在磁盘的什么地方吗? 5.文件名最长多长?受什么制约? 6.文件名太长了会影响系统性能吗?为什么会产生影响? 7.一个目录

linux文件系统学习总结

linux最优秀的特点在于它是多用户多任务的环境,而且对于linux来讲一切皆文件,提到文件这个概念就免不了提文件相关的权限与属性的概念,那相关文件的属性记录在硬盘的哪个地方呢?这就需要了解linux的文件系统是如何记录文件,如何读取文件. 大家都知道硬盘作为存储介质,如果要使用硬盘存储数据需要对硬盘进行分区,格式化之后才可以存储数据.那为什么要对硬盘进行分区呢?因为我们必须要告诉操作系统:"这块硬盘可以访问的区域是有A柱面到B柱面",只有这样,操作系统才能控制硬盘磁头去A~B范围内的

Vim,find,bash,Linux文件系统的特殊权限2015.8.30作业

一   Vim 1.vim的使用方法 1.1 三种模式化 编辑模式.输入模式.末行模式 1.2 模式转换 编辑模式 --> 输入模式: i:在当前光标所在字符的前面,转为输入模式 a:在当前光标所在字符的后面,转为输入模式 o:在当前光标所在行的下方,新建一行,并转为输入模式 I:在当前光标所在行的行首,转为输入模式 A:在当前光标所在行的行尾,转为输入模式 O:在当前光标所在行的上方,新建一行,并转为输入模式 输入模式 --> 编辑模式:ESC 编辑模式 --> 末行模式:: 末行模式