内核下读写文件
原创
©著作权归作者所有:来自51CTO博客作者tcspecial的原创作品,请联系作者获取转载授权,否则将追究法律责任
内核中操作文件函数与用户层read,write这样API不同,需要使用内核空间专用的一套函数。
文件API
struct file *filp_open(const char *filename, int flags, int mode);
打开文件
int filp_close(struct file *filp, fl_owner_t id);
关闭文件,参数id为POSIX线程ID,一般设NULL
struct file
{
struct path f_path; //文件路径
const struct file_operations *f_op; //文件操作结构,定义了读写等众多操作函数
spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */
...
};
/*
* NOTE:
* read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
* can be called without the big kernel lock held in all filesystems.
*/
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); //读
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); //写
...
}
测试
static void read_file( void )
{
char szBuff[210] = {};
mm_segment_t oldfs;
// 打开文件
fp = filp_open("/etc/redis/test.conf",O_RDWR,0);
if(!fp || IS_ERR(fp))
{
printk(KERN_ALERT "fail to open test.conf\n");
return -1;
}
// read
if(!fp->f_op || !fp->f_op->read)
{
printk(KERN_ALERT "Can't read file\n");
return -1;
}
oldfs = get_fs(); // 获取原先地址空间设置
set_fs(KERNEL_DS); // 设置为内核空间
if(fp->f_op->read(fp,szBuff,210,&fp->f_pos) == 0)// 执行fp的read函数
{
printk(KERN_ERR "Error in read file\n");
return -1;
}
set_fs(oldfs);// 还原为原先地址空间设置
printk(KERN_ALERT "%s\n",szBuff);
// 关闭文件
filp_close(fp);
return 0;
}