cat function calling read() infinite times

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

I am working on simple character device driver. I have implemented read and write functions in the module, the problem is when I try to read the device file using cat /dev/devicefile it is going into infinite loop i.e. reading the same data repeatedly. Can someone suggest me any solution to this problem? Below is my driver code.

#include #include #include #include #include MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("character device driver"); MODULE_AUTHOR("Srinivas");  static char msg[100]={0};  static int t;  static int dev_open(struct inode *, struct file *); static int dev_rls(struct inode *, struct file *); static ssize_t dev_read(struct file *, char *,size_t, loff_t *); static ssize_t dev_write(struct file *, const char *, size_t,loff_t *);  static struct file_operations fops = {     .read = dev_read,     .open = dev_open,     .write = dev_write,     .release = dev_rls, }; static int himodule( void ) {     t = 0;     t = register_chrdev(0, "chardevdriver", &fops);     if (t  0) {         msg[count] = buff[count];         len--;         count++;     }     return count; }  static int dev_rls(struct inode *inod,struct file *fil) {     printk(KERN_ALERT"device closed\n");     return 0; } module_init(himodule); module_exit(byemodule); 

回答1:

.read function should also correctly process its len and off arguments. The simplest way to implement reading from memory-buffered file is to use simple_read_from_buffer helper:

static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off) {     return simple_read_from_buffer(buff, len, off, msg, 100); } 

You can inspect code of that helper (defined in fs/libfs.c) for educational purposes.

BTW, for your .write method you could use simple_write_to_buffer helper.



回答2:

You are not respecting the buffer size passed into the dev_read function, so you may be invoking undefined behaviour in cat. Try this:

static ssize_t dev_read( struct file *filp, char *buff, size_t len, loff_t  *off ) {     size_t count = 0;     printk( KERN_ALERT"inside read %d\n", *off );     while( msg[count] != 0 && count 


回答3:

This problem can be solved by correctly setting *off (fourth parameter of my_read()).

You need to return count for the first time and zero from second time onwards.

if(*off == 0) {     while (msg[count] != 0) {         put_user(msg[count], buff++);         count++;         (*off)++;     }     return count; } else return 0; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!