open函数的流程

1.          引言
      从事Linux环境工作2年有余,一直懵懵懂懂,1年前拜读了《莱昂氏UNIX源代码分析》一书,感觉自己的学习道路漫漫且修远。最近受chinaunix的精华文帖启发,拟将近来的部分内核调用分析笔记拿出来与各前辈先进共同探讨学习,以壮个人学习之路。
      本部分主要讲述的是文件I/O操作的2.6.11内核版本实现,包括了主要的数据结构、宏定义和函数流程。以下分别讲述open,create,close,read,write,lseek系统调用。
2.          主要参考
《莱昂氏UNIX源代码分析》
《UNIX环境高级编程》
    www.kernel.org
3.          主要数据结构
3.1.          FD
        对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。
      当读、写一个文件时,用open或creat返回的文件描述符fd标识该文件,将其作为参数传送给read或write。在POSIX.1应用程序中,文件描述符为常数0、1和2分别代表STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO,意即标准输入,标准输出和标准出错输出,这些常数都定义在头文件;中。
文件描述符的范围是0~OPEN_MAX,在目前常用的linux系统中,是32位整形所能表示的整数,即65535,64位机上则更多。
3.2.          File
struct file {
     struct list_head          f_list; //文件链表指针
    struct dentry                  *f_dentry; // 文件对应的目录结构
    struct vfsmount           *f_vfsmnt; // 虚拟文件系统挂载点
    struct file_operations          *f_op; // 文件操作函数指针
    atomic_t                  f_count;
     unsigned int                   f_flags;
     mode_t                          f_mode; // 文件模式
    int                          f_error;
     loff_t                          f_pos; // 文件offset
     struct fown_struct          f_owner; //文件owner 结构
    unsigned int                  f_uid, f_gid;
     struct file_ra_state          f_ra; // 跟踪上次文件操作状态的结构指针
    size_t                          f_maxcount; // 文件大小
    unsigned long                  f_version;
     void                          *f_security; // hook 文件操作的security结构指针
    void                          *private_data; // tty 驱动器所需数据
#ifdef CONFIG_EPOLL
     struct list_head          f_ep_links; // EPOLL 机制检测所需链表结构
    spinlock_t                  f_ep_lock; // 兼容早期gcc bug 的标志
#endif /* #ifdef CONFIG_EPOLL */
     struct address_space          *f_mapping; // 地址映射表
}
3.3.          File_struct
File_struct结构保存了进程打开的所有文件表数据。
struct files_struct {
     atomic_t count; // 自动增量
    spinlock_t file_lock; // 低位成员保护标识
    int max_fds; // 最大文件句柄数目
    int max_fdset; // 最大的fd集合容量
    int next_fd; // 下一个空闲fd
     struct file ** fd; // 当前fd对应的文件结构指针列表
    fd_set *close_on_exec; // 可执行close的fd集合
    fd_set *open_fds; // 打开的fd集合
    fd_set close_on_exec_init; //
     fd_set open_fds_init;
     struct file * fd_array[NR_OPEN_DEFAULT]; // 默认打开的fd队列
};
4.          open 函数
4.1.          原型与参数
     int open(const char * pathname,    int oflag, .../*, mode_t mode * / )    -1代表错误。
     这里的oflag是一个整形,主要供open 函数使用,部分fcntl函数也会使用。详细的说明请用 man 2 open就可以看到了。以下列出了2.6内核定义的open和fcntl函数所使用的flag宏定义,说明的格式如宏定义名称;: 描述。
O_ACCMODE          ;: 读写文件操作时,用于取出flag的低2位。
O_RDONLY;: 只读打开
O_WRONLY;: 只写打开
O_RDWR;: 读写打开
O_CREAT;: 文件不存在则创建,需要mode_t,not fcntl
O_EXCL;: 如果同时指定了O_CREAT,而文件已经存在,则出错, not fcntl
O_NOCTTY;: 如果pathname指终端设备,则不将此设备分配作为此进程的控制终端。O_TRUNC;: 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。      O_APPEND;: 每次写时都加到文件的尾端
O_NONBLOCK;: 如果p a t h n a m e指的是一个F I F O、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I / O操作设置非阻塞方式。
O_NDELAY;;
O_SYNC;: 使每次write都等到物理I/O操作完成。
FASYNC;: 兼容BSD的fcntl同步操作
O_DIRECT;: 直接磁盘操作标识
O_LARGEFILE;: 大文件标识
O_DIRECTORY;:          必须是目录
O_NOFOLLOW;: 不获取连接文件
O_NOATIME;: 暂无
当新创建一个文件时,需要指定mode 参数,以下说明的格式如宏定义名称;: 描述。
     S_IRWXU;:文件拥有者有读写执行权限
     S_IRUSR (S_IREAD);:文件拥有者仅有读权限
     S_IWUSR (S_IWRITE);:文件拥有者仅有写权限
     S_IXUSR (S_IEXEC);:文件拥有者仅有执行权限
     S_IRWXG;:组用户有读写执行权限
     S_IRGRP;:组用户仅有读权限
     S_IWGR
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值