【文件管理】其他文件操作

来源:互联网 发布:linux命令vi与gedit 编辑:程序博客网 时间:2024/05/16 15:22

系统调用open(),close(),write(),read()无疑是最基本,最重要的文件操作;除此以外,还有许多文件操作和文件操作相关的系统调用;


(1)在sys_lssek()中,参数origin只能是0,1,2;这个系统调用只能处理32位系统,也就是只能处理文件大小小于4GB的文件爱你,大于4GB文件,请采用llseek();但是最终也都会调用llseek();如果相应的文件系统,没有实现该函数,就调用default_llseek();而对于ext2文件系统,最终调用的是ext2_file_lseek();在ext2_file_lseek()中,设置file中的f_ops,既然当前设置位置变化了,那原来的预读也就放弃了;如果将lseek()与write()结合起来,空洞内的内容是要到等待正真写的时候才会为之分配记录块,在这之前的读都是0;

(2)在sys_dup()中,是用来复制一个打开文件号,使新的打开文件号也代表着原已存在的文件也代表着文件操作上下文;首先找到原fd的file结构;dupfd()从打开文件号start开始巽宅空闲数组的元素;找到了空闲的打开文件号,就可以通过allocate_fd()将file结构和这个新的fd连接起来;

(3)上述的sys_dup(),Linux各种的shell重定向机制就是建立这个系统调用的基础之上的;先看这么一条shell命令:echo xxw;这条命令要求shell进程执行一个可执行文件echo,参数是what is dup;接到这条命令,shell进程先找到可执行文件bin/echo,然后fork()出一个子进程让它执行/bin/echo,并将参数传递给它,这个进程从shell继承了标准输入,标准输出,标准输出信息通道,即打开文件号为0,1,2的三个已打开文件,然后就可把它输出到显示屏;但是重定向到磁盘文件foo中,即echo xxw > foo;步骤如下:

(3.1)打开或创建文件foo,并截去foo原有的内容,其打开文件号为3;

(3.2)通过dup()复制已打开文件stdout,也就是将打开文件号为1的file结构复制到打开文件号为4处,目的是将stdout的file指针暂存一下;

(3.3)关闭stdout,即1号已打开文件,由于它的file结构已经被复制到打开文件打开号为4;这个文件(显示屏)实际上并没有最终关闭,只是把stdout的哇位置腾了出来;

(3.4)通过dup(),复制3号已打开文件,由于此时1号文件的位置已经空闲,所以stdout的file结构指针指向了磁盘文件foo;

(3.5)通过fork()和exec()创建子进程执行echo,子进程在执行echo之前会将已打开文件号3,4关闭,只剩下0,1,2;但是此时已打开文件实际上已经指向磁盘文件foo,所以echo将输出往stdout写时就写进了文件foo;

(3.6)对于shell进程,关闭指向foowen的1号和3号文件,并且通过dup()和close()将原来指向显示屏的file结构指针恢复到stdout,这样shell进程就恢复了开始的三个标准已打开文件;

(4)由此可见,可执行程序echo并不知道它的标准输出文件stdout实际通向何方,进程与实际输出文件的结合是由其父进程包办的;对于stdin,和stderr其实也是一样的;

(5)对于系统调用ioctl(),不适合为之专门设置一个系统调用,就可以归入这个系统调用,尤其是对一些命令进行一些扩充;在sys_ioctl(),参数fd为目标文件的打开文件号,cmd则为具体的操作命令代码(内核中已有一些定义,如FLOCLEX,FIONCLES,FIONBIO等,用户可根据规则来扩展),arg是参数(可以封装到一个数据结构中,然后arg用作指向数据结构的指针);

(6)对于常规文件的操作还要通过file_ioctl()加上一层过滤,而对设备文件或其他FIFO文件的处理直接由具体的file_operations结构的函数指针ioctl提供;在file_ioctl()中,FIBMAP可以根据给定逻辑号得到对应的物理块号;FIGETBSZ返回文件所在设备的记录块大小;FIONREAD返回文件中从当前读写位置举例文件末尾的距离;一个文件系统至少有一个file_operations,如ext2,一个是ext2_file_operations,另一个是ext2_dir_operations,分别对应于常规文件和目录;对于设备文件和特殊文件,甚至每一个文件都有自己的file_operations;

(7)对于系统调用link(),这个系统调用为已存在的文件增加一个别名,由link()所建立的硬链接,有别于symlink建立的符号链接;在sys_link()中,新建的目录项与原来的目录项都指向同一个inode结构,通过函数ext2_add_entry和d_instantiat()完成,这样inode结构中的i_dentry队列(这个队列中所有的dentry指向同一个inode结构)中就多了一个dentry结构;

0 0
原创粉丝点击