【Linux】File 结构体,和 fd 的关系
来源:互联网 发布:美分知乎 编辑:程序博客网 时间:2024/05/29 16:40
struct file { union { struct list_head fu_list; //文件对象链表指针 linux/include/linux/list.h struct rcu_head fu_rcuhead; //RCU(Read-Copy Update) 是 Linux 2.6 内核中新的锁机制 #define f_dentry f_path.dentry //f_path的成员之一,当前文件的 dentry 结构 } f_u; struct path f_path; //包含 dentry 和 mnt 两个成员,用于确定文件路径 const struct file_operations *f_op; //与该文件相关联的操作函数 #define f_vfsmnt f_path.mnt //表示当前文件所在文件系统的挂载根目录 atomic_t f_count; //文件的引用计数(有多少进程打开该文件) off_t f_pos; //该文件在当前进程中的文件偏移量 unsigned int f_flags; //对应于 open 时指定的 flag mode_t f_mode; //读写模式:open 的 mod_t mode 参数 struct file_ra_state f_ra; //在 linux/include/linux/fs.h 中定义,文件预读相关 struct fown_struct f_owner; //该结构的作用是通过信号进行 I/O 时间通知的数据。 unsigned int f_uid, f_gid; //文件所有者 id,所有者组 id unsigned long f_version; spinlock_t f_ep_lock; #ifdef CONFIG_SECURITY void *f_security; #endif void *private_data; #ifdef CONFIG_EPOLL struct list_head f_ep_links; #endif }; struct address_space *f_mapping;
2. Linux 文件描述符与 C FILE之间的关系
1. linux 文件描述符
对于 linux 而言,所有对设备和文件的操作都是使用文件描述符来进行的。文件描述符是一个非负的整数,它是一个索引值,指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。通常,一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这 3 个文件分别对应文件描述符为0、1和2(宏 STD_FILENO、STDOUT_FILENO 和STDERR_FILENO)。
2.内核中的实现细节:
linux 用一个数组来管理进程打开的文件的 file 对象,数组中的每一个元素都存放了一个指向进程所打开的文件的 file 对象。数组的下标用来访问文件。linux 把数组元素的下标叫做该数组元素所对应文件的文件描述符,这个描述符就是系统对文件的标识,也叫做文件描述符数组。(注:内核可以通过系统调用函数 dup( )、dup2( ) 和 fctl( ) 将数组中的多个元素指向同一个文件的 file 对象。即同一个文件可以有多个文件描述符。)文件描述符表在 files_struct 结构中定义,为 structfile*fd_array[NR_OPEN_DEFAULT]; 进程与文件系统及其所打开文件的关系如图所示:
3.进程打开一个文件的具体流程
进程通过系统调用 open( ) 来打开一个文件,实质上是获得一个文件描述符,以便进程通过文件描述符为连接对文件进行其他操作。进程打开文件时,会为该文件创建一个 file对象,并把该 file 对象存入进程打开文件表中(文件描述符数组),进而确定了所打开文件的文件描述符。open( ) 操作在内核里通过 sys_open( ) 实现,sys_open( ) 将创建文件的 dentry、inode 和 file 对象,并在 file_struct 结构体的进程打开文件表 fd_array[NR_OPEN_DEFAULT] 中寻找一个空闲表项,然后返回这个表项的下标(索引),即文件描述符。创建文件的 file 对象时,将 file 对象的 f_op 指向了所属文件系统的操作函数集 file_operations,而该函数集又来自具体文件的i节点,于是虚拟文件系统就与实际文件系统的操作衔接起来了。
4. C 标准库中的 FILE 结构和文件描述符、files_struct 和 file 结构之间的关系早期的 C 标准库中,FILE 在 stdio.h 中定义;Turbo C 中,参见谭浩强的《C程序设计》,FILE 结构体中包含成员 fd,即文件描述符。在 glibc- 2.9 中,stdio.h 中定义 FILE为 _IO_FILE 类型,而 FILE 为 _IO_FILE 在 /glibc-2.9/libio/libio.h 中定义,如下所示,亦可以在安装的 Ubuntu 系统的 /usr/include/stdio.h 中找到:
struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; restis flags. */#define _IO_file_flags _flags /* The following pointerscorrespond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_endfields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. */ /* The following fields areused to support backing up and undo. */ char *_IO_save_base; /*Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backuparea */ char *_IO_save_end; /*Pointer to end of non-current get area. */ struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno;#if 0 int _blksize;#else int _flags2;#endif _IO_off_t _old_offset; /*This used to be _offset but it's too small. */#define __HAVE_COLUMN /* temporary */ /* 1+column number ofpbase(); 0 is unknown. */ unsigned short _cur_column; signed char _vtable_offset; char _shortbuf[1]; /* char* _save_gptr; char* _save_egptr; */ _IO_lock_t *_lock;#ifdef _IO_USE_OLD_IO_FILE};
当然,上面的结构体太复杂,我们只关心需要的部分-文件描述符即可。文件描述符的分配是从小到大逐个查询文件描述符是否已经使用,然后再分配。
file 在 /include/linux/fs.h 中定义,从进程的角度来看,文件就是一个 file 结构的实例,也常常叫 file 对象。file 对象是进程调用open 打开一个文件,linux 虚拟文件系统根据进程请求创建的一个 file 对象。进程通过该文件的 file 结构了解和操作文件。
struct file { /* * fu_list becomes invalid after file_free iscalled and queued via * fu_rcuhead for RCU freeing */ union{ struct list_head fu_list; struct rcu_head fu_rcuhead; }f_u; struct path f_path;#define f_dentry f_path.dentry#define f_vfsmnt f_path.mnt const struct file_operations *f_op; atomic_t f_count; unsigned int f_flags;mode_t f_mode; loff_t f_pos; struct fown_struct f_owner; unsigned int f_uid, f_gid; struct file_ra_state f_ra; u64 f_version;#ifdef CONFIG_SECURITY void *f_security;#endif /*needed for tty driver, and maybe others */ void *private_data;#ifdef CONFIG_EPOLL /* Used by fs/eventpoll.c to link all thehooks to this file */ struct list_head f_ep_links; spinlock_t f_ep_lock;#endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping;#ifdef CONFIG_DEBUG_WRITECOUNT unsigned long f_mnt_write_state;#endif};
文件描述符数组中存放了一个进程所打开的所有文件。文件描述符数组包含在进程打开的文件表 files_struct 结构中。在 /include/linux/fdtable.h 中定义,为一个指向 file类型的指针数组---fd_array[NR_OPEN_DEFAULT],其中 NR_OPEN_DEFAULT 也在 fdtable.h 中定义,这是一个和具体的 CPU 体系结构有关的变量,#define NR_OPEN_DEFAULTBITS_PER_LONG。以 x86 体系为例,BITS_PER_LONG 在 /include/asm-x86/types.h 中定义,32 位 CPU 为 32,64 位 CPU 为 64。
struct files_struct { /* * read mostly part */ atomic_t count; struct fdtable *fdt; struct fdtable fdtab; /* * written part on aseparate cache line in SMP */ spinlock_t file_lock____cacheline_aligned_in_smp; int next_fd; struct embedded_fd_setclose_on_exec_init; struct embedded_fd_setopen_fds_init; struct file * fd_array[NR_OPEN_DEFAULT];};
FILE 结构和文件描述符 fd、files_struct 和 file 结构之间的关系如下图所示:
以上就是我关于 File 和 fd 各方面的理解,希望对你有所帮助。
0 0
- 【Linux】File 结构体,和 fd 的关系
- 简析文件描述符(fd)和FILE结构体的关系
- 文件描述符(fd)和FILE结构体的关系
- 简析文件描述符(fd) 和 FILE结构体的关系
- 浅析FILE和fd之间的关系
- FILE内容和fd之间的关系
- linux中文件描述符fd和struct file结构体的释放
- linux中文件描述符fd和struct file结构体的释放
- linux中文件描述符fd和struct file结构体的释放
- 探索文件描述符(fd)与FILE结构体之间的关系
- 探索文件描述符(fd)与FILE结构体之间的关系
- fd与FILE*的关系
- 文件描述符fd和FILE的关系
- 浅析文件描述符fd和FILE结构体
- 文件描述符(fd)与file结构体及其关系
- FILE结构体与fd文件标识符
- Linux下的FILE*与fd
- 文件描述符fd与文件指针FILE*的关系
- YOLOv2论文理解
- IOS CollectionView 拖拽移动
- Activity 的启动模式
- Linux内核系统调用的添加
- GRAN论文翻译
- 【Linux】File 结构体,和 fd 的关系
- 大数据-Hadoop学习笔记09
- 归并排序
- spring中bean的配置
- 学习笔记之SharedPreference问题解答
- HDU
- IOS 动态获取键盘高度
- 使用DocumentFragment加快DOM渲染速度
- 大数据系列-scala类型定义