Linux 内核驱动里对文件的操作

来源:互联网 发布:c linux sleep 编辑:程序博客网 时间:2024/05/16 14:13
Linux 文件打操作
1.创建
int creat(const char *filename, mode_t mode);
umask一起决定文件的最终权限(mode&umask)
umask 可以通过unmsk();来改变。


2.打开
int open(const char *filename, int flags);
int open(const char *filename, int flags, mode_t mode);
flags :文件打开标志
O_RDONLY   只读
O_WRONLY   只写
O_RDWR     读写
O_APPEND   追加
O_CREAT 创建
O_EXEC     如果使用了O_CREAT且文件存在,就会发生一个错误
O_NOBLOCK  以非阻塞方式打开一个文件
O_TRUNC    如果文件已经存在,则删除文件的内容


O_RDONLY O_WRONLY O_RDWR 只能使用其中一个。不能同时使用多个


文件访问权限
S_IRUSR 用户可读
S_IWUSR 用户可写
S_IXUSR 用户可执行
S_IRWXU 用户可读、写、执行


S_IRGRP 组可读
S_IWGRP 组可写
S_IXGRP 组可执行
S_IRWXG 组可读、写、执行


S_IROTH 其他人可读
S_IWOTH 其他人可写
S_IXOTH 其他人可执行
S_IRWXO 其他人可读、写、执行


S_ISUID 设置用户的执行ID
S_ISGID 设置组的执行ID




3.读写
int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);


4.移位
int lseek(int fd, offset_t offset, int whence);
whence 参数有以下值:
SEEK_SET : 相对文件开头。
SEEK_CUR:相对文件读写指针当前位置。
SEEK_END:相对文件末尾。


5.关闭
int close(int fd);


以下源码摘自《全志平台Android  STK G-senser驱动》

Linux kernel 文件操作:
#include <asm/uaccess.h>
#include <linux/fs.h>   
#include <linux/syscalls.h>


#define STK_ACC_CALI_FILE "/data/misc/stkacccali.conf"  //文件


static int32_t stk_get_file_content(char * r_buf, int8_t buf_size)  //读取文件内容到r_buf数组
{
struct file  *cali_file;
mm_segment_t fs;
ssize_t ret;

    cali_file = filp_open(STK_ACC_CALI_FILE, O_RDONLY,0);
    if(IS_ERR(cali_file))
{
        printk(KERN_ERR "%s: filp_open error, no offset file!\n", __func__);
        return -ENOENT;
}
else
{
fs = get_fs();
set_fs(get_ds());
ret = cali_file->f_op->read(cali_file,r_buf, STK_ACC_CALI_FILE_SIZE,&cali_file->f_pos);
if(ret < 0)
{
printk(KERN_ERR "%s: read error, ret=%d\n", __func__, ret);
filp_close(cali_file,NULL);
return -EIO;
}
set_fs(fs);
    }

    filp_close(cali_file,NULL);
return 0;
}
 
static int stk_store_in_file(char offset[], char mode) //将offset数组内容写入到文件。
{
struct file  *cali_file;
char r_buf[STK_ACC_CALI_FILE_SIZE] = {0};
char w_buf[STK_ACC_CALI_FILE_SIZE] = {0};
mm_segment_t fs;
ssize_t ret;
int8_t i;

w_buf[0] = STK_ACC_CALI_VER0;
w_buf[1] = STK_ACC_CALI_VER1;
w_buf[2] = offset[0];
w_buf[3] = offset[1];
w_buf[4] = offset[2];
w_buf[5] = mode;

    cali_file = filp_open(STK_ACC_CALI_FILE, O_CREAT | O_RDWR,0666);

    if(IS_ERR(cali_file))
{
        printk(KERN_ERR "%s: filp_open error!\n", __func__);
        return -STK_K_FAIL_OPEN_FILE;
}
else
{
fs = get_fs();
set_fs(get_ds());

ret = cali_file->f_op->write(cali_file,w_buf,STK_ACC_CALI_FILE_SIZE,&cali_file->f_pos);
if(ret != STK_ACC_CALI_FILE_SIZE)
{
printk(KERN_ERR "%s: write error!\n", __func__);
filp_close(cali_file,NULL);
return -STK_K_FAIL_W_FILE;
}
cali_file->f_pos=0x00;
ret = cali_file->f_op->read(cali_file,r_buf, STK_ACC_CALI_FILE_SIZE,&cali_file->f_pos);
if(ret < 0)
{
printk(KERN_ERR "%s: read error!\n", __func__);
filp_close(cali_file,NULL);
return -STK_K_FAIL_R_BACK;
}
set_fs(fs);

//printk(KERN_INFO "%s: read ret=%d!\n", __func__, ret);
for(i=0;i<STK_ACC_CALI_FILE_SIZE;i++)
{
if(r_buf[i] != w_buf[i])
{
printk(KERN_ERR "%s: read back error, r_buf[%x](0x%x) != w_buf[%x](0x%x)\n", 
__func__, i, r_buf[i], i, w_buf[i]);
filp_close(cali_file,NULL);
return -STK_K_FAIL_R_BACK_COMP;
}
}
    }
    filp_close(cali_file,NULL);

#ifdef STK_PERMISSION_THREAD
fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_chmod(STK_ACC_CALI_FILE , 0666);
ret = sys_fchmodat(AT_FDCWD, STK_ACC_CALI_FILE , 0666);
set_fs(fs);
#endif
//printk(KERN_INFO "%s successfully\n", __func__);
return 0;
}