void write_mac_to_file(const char *file_path, const unsigned char *mac)
{
FILE *f;
unsigned char mac_src[MAC_LEN];
char buf[100];
f = fopen(file_path, "w");
if (f == NULL) return;
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
fputs(buf, f);
WCND_LOGD("write mac to configuration file: %s", buf);
fclose(f);
sprintf(buf, "chmod 666 %s", file_path);
system(buf);
}
或者这么用,记得打开和写要配套哦。不然就bad file number 啦
if(NULL != (fd = open(IWNPI_EXEC_TMP_FILE, O_RDWR|O_CREAT|O_SYNC|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)))
{
int write_cnt = 0;
write_cnt = write(fd,ret_result_buf,sizeof(ret_result_buf));
close(fd);
} else {
ALOGD("open error=%d, %s\n",errno, strerror(errno));
}
kernel 4.4版本上, read不能用filp->f_op->read;建议使用vfs_read
if(file == NULL)
file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);
if (IS_ERR(file)) {
printk("error occured while opening file %s, exiting...\n", MY_FILE);
return 0;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
vfs_write(file, (char *)buf, sizeof(buf), &file->f_pos);
set_fs(old_fs);
filp_close(file, NULL);
这里为什么vfs_write 前要set_fs(KERNEL_DS)?
ssize_t vfs_read(struct file* filp, char __user* buffer, size_t len, loff_t* pos);
ssize_t vfs_write(struct file* filp, const char __user* buffer, size_t len, loff_t*pos);
注意这两个函数的第二个参数buffer,前面都有__user修饰符,这就要求这两个buffer指针都应该指向用空的内存,如果对该参数传递kernel空间的指针,这两个函数都会返回失败-EFAULT。但在Kernel中,我们一般不容易生成用户空间的指针,或者不方便独立使用用户空间内存。要使这两个读写函数使用kernel空间的buffer指针也能正确工作,需要使用set_fs()函数或宏(set_fs()可能是宏定义),如果为函数,其原形如下:
void set_fs(mm_segment_t fs);
该函数的作用是改变kernel对内存地址检查的处理方式,其实该函数的参数fs只有两个取值:USER_DS,KERNEL_DS,分别代表用户空间和内核空间,默认情况下,kernel取值为USER_DS,即对用户空间地址检查并做变换。那么要在这种对内存地址做检查变换的函数中使用内核空间地址,就需要使用set_fs(KERNEL_DS)进行设置。
对应X86 android7.0 kernel4.4平台代码,发现不添加set_fs确实返回-14错误:
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
return -EFAULT;
}
#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
#define __range_ok(addr,size) ({ unsigned longflag,roksum; __chk_user_ptr(addr); asm("addl %3,%1 ; sbbl %0,%0; cmpl%1,%4; sbbl $0,%0" :"=&r" (flag), "=r" (roksum) :"1" (addr),"g"((int)(size)),"rm" (current_thread_info()->addr_limit.seg)); flag; })
#define set_fs(x)(current_thread_info()->addr_limit = (x))