|
O_APPEND<02000>;: 每次写时都加到文件的尾端
O_NONBLOCK<04000>;: 如果p a t h n a m e指的是一个F I F O、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I / O操作设置非阻塞方式。
O_NDELAY;;
O_SYNC<010000>;: 使每次write都等到物理I/O操作完成。
FASYNC<020000>;: 兼容BSD的fcntl同步操作
O_DIRECT<040000>;: 直接磁盘操作标识
O_LARGEFILE<0100000>;: 大文件标识
O_DIRECTORY<0200000>;: 必须是目录
O_NOFOLLOW<0400000>;: 不获取连接文件
O_NOATIME<01000000>;: 暂无
当新创建一个文件时,需要指定mode 参数,以下说明的格式如宏定义名称<实际常数值>;: 描述。
S_IRWXU<00700>;:文件拥有者有读写执行权限
S_IRUSR (S_IREAD)<00400>;:文件拥有者仅有读权限
S_IWUSR (S_IWRITE)<00200>;:文件拥有者仅有写权限
S_IXUSR (S_IEXEC)<00100>;:文件拥有者仅有执行权限
S_IRWXG<00070>;:组用户有读写执行权限
S_IRGRP<00040>;:组用户仅有读权限
S_IWGRP<00020>;:组用户仅有写权限
S_IXGRP<00010>;:组用户仅有执行权限
S_IRWXO<00007>;:其他用户有读写执行权限
S_IROTH<00004>;:其他用户仅有读权限
S_IWOTH<00002>;:其他用户仅有写权限
S_IXOTH<00001>;:其他用户仅有执行权限
4.2.实现分析
4.2.1.主要函数调用关系图
sys_open( 见4.2.2 节)
| ----------- getname( 见4.2.3 节 )
| ----------- filp_open( 见4.2.4节 )
| | ------------ open_namei( 见4.2.4.1节 )
| | | ----------- may_open( 见4.2.4.1.1节 )
| | ------------ dentry_open( 见4.2.4.2节 )
|
4.2.2.主调用函数sys_open
asmlinkage long sys_open(const char __user * filename, int flags, int mode){
char * tmp;
int fd, error;
// 如果不是32位处理器,则增加大文件标识
#if BITS_PER_LONG != 32
flags |= O_LARGEFILE;
#endif
// 为了提高使用效率,在使用之前先把文件名拷贝到内核数据区。见3.2.2说明
tmp = getname(filename);
// 获取到返回值,如果出错,则返回,否则执行打开操作。
fd = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
// 从进程的文件表中找出一个空闲的文件表指针,如果出错,则返回
fd = get_unused_fd();
if (fd >;= 0) {
// 执行打开操作。见3.2.3说明
struct file *f = filp_open(tmp, flags, mode);
// 获取返回结果,如果出错,则跳转至out_error,否则执行fd_install
error = PTR_ERR(f);
if (IS_ERR(f))
goto out_error;
// 添加打开的文件表 f 到当前进程的文件表队列中。见3.2.4说明
fd_install(fd, f);
}
out:
// 释放getname分配的内存空间
putname(tmp);
}
return fd;
out_error:
// 把文件表指针返回到进程的文件表中,并返回错误代码。
put_unused_fd(fd);
fd = error;
goto out;
}
|
4.2.3.sys_open子函数getname
getname函数主要功能是在使用文件名之前把其拷贝到内核数据区,正常结束时返回内核分配的空间首地址,出错时返回错误代码。其调用了函数do_getname来实现。
共6页: 上一页 [1] 2 [3] [4] [5] [6] 下一页
|