cat function calling read() infinite times

瘦欲@ 提交于 2019-11-26 08:39:19

问题


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<linux/module.h>
#include<linux/fs.h>
#include<linux/string.h>
#include<asm/uaccess.h>
#include<linux/init.h>
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)
        printk(KERN_ALERT\"device registration failed\\n\");
    else
        printk(KERN_ALERT\"device registered successfully\\n\");

    printk(KERN_ALERT\"major number is %d\", t);
    return 0;
}
static void byemodule(void)
{
    unregister_chrdev(t, \"chardevdriver\");
    printk(KERN_ALERT\"successfully unregistered\\n\");
}

static int dev_open(struct inode *inod, struct file *fil)
{
    printk(KERN_ALERT\"inside the dev open\");
    return 0;
}
static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
    short count = 0;
    while (msg[count] != 0) {
        put_user(msg[count], buff++);
        count++;
    }
    return count;
}

static ssize_t dev_write(struct file *filp, const char *buff, size_t len, loff_t *off)
{
    short count = 0;
    printk(KERN_ALERT\"inside write\\n\");

    memset(msg,0,100);

    printk(KERN_ALERT\" size of len is %zd\",len);

    while (len > 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 < len )
    {
        put_user( msg[count], buff++ );
        count++;
    }
    return 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;


来源:https://stackoverflow.com/questions/31563107/cat-function-calling-read-infinite-times

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