14.15 获得文件属性
14.15.1 ls命令的幕后功臣
ls
命令中调用了大量的系统调用 stat64
和write
,其中stat64
用于获得文件的属性信息, write
用于把信息输出到屏幕,即标准输出。这里的 stat64
表示 64 位版本的 stat
。 其函数原型是int stat(const char* path, struct stat *buf)
;
14.15.2 实现sys_stat
先增加记录文件属性的结构体:
/* 文件属性结构体 */
struct stat
{
uint32_t st_ino; // inode编号
uint32_t st_size; // 尺寸
enum file_types st_filetype; // 文件类型
};
//定义在fs.h
咱们的 struct stat
很简单,只有 3 个成员,因此只能获得 3 个属性。
/* 在buf中填充文件结构相关信息,成功时返回0,失败返回-1 */
int32_t sys_stat(const char *path, struct stat *buf)
{
/* 若直接查看根目录'/' */
if (!strcmp(path, "/") || !strcmp(path, "/.") || !strcmp(path, "/.."))
{
buf->st_filetype = FT_DIRECTORY;
buf->st_ino = 0;
buf->st_size = root_dir.inode->i_size;
return 0;
}
int32_t ret = -1; // 默认返回值
struct path_search_record searched_record;
memset(&searched_record, 0, sizeof(struct path_search_record)); // 记得初始化或清0,否则栈中信息不知道是什么
int inode_no = search_file(path, &searched_record);
if (inode_no != -1)
{
struct inode *obj_inode = inode_open(cur_part, inode_no); // 只为获得文件大小
buf->st_size = obj_inode->i_size;
inode_close(obj_inode);
buf->st_filetype = searched_record.file_type;
buf->st_ino = inode_no;
ret = 0;
}
else
{
printk("sys_stat: %s not found\n", path);
}
dir_close(searched_record.parent_dir);
return ret;
}
sys_stat
:接受 2 个参数,待获取属性的文件路径 path
、存储属性的缓冲区 buf
,功能是在 buf
中填充文件结构相关信息,成功时返回 0,失败返回-1 。
首先判断是不是根目录,然后在调用search_file
获得该路径对应的inode
索引,然后调用inode_open
将该inode
调入内存,将属性直接写在buf
中。