Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cat函数调用read()无限次_C_Linux Kernel_Linux Device Driver - Fatal编程技术网

cat函数调用read()无限次

cat函数调用read()无限次,c,linux-kernel,linux-device-driver,C,Linux Kernel,Linux Device Driver,我正在开发简单字符设备驱动程序。我在模块中实现了读写功能,问题是当我尝试使用cat/dev/devicefile读取设备文件时,它将进入无限循环,即重复读取相同的数据。有人能给我提出解决这个问题的办法吗?下面是我的驱动程序代码 #include<linux/module.h> #include<linux/fs.h> #include<linux/string.h> #include<asm/uaccess.h> #include<linux

我正在开发简单字符设备驱动程序。我在模块中实现了读写功能,问题是当我尝试使用
cat/dev/devicefile
读取设备文件时,它将进入无限循环,即重复读取相同的数据。有人能给我提出解决这个问题的办法吗?下面是我的驱动程序代码

#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);
#包括
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
模块描述(“字符设备驱动程序”);
模块作者(“Srinivas”);
静态字符msg[100]={0};
静态int t;
静态int dev_open(结构索引节点*,结构文件*);
静态int dev_rls(结构索引节点*,结构文件*);
静态ssize_t dev_read(结构文件*,字符*,大小,loff_t*);
静态ssize_t dev_write(结构文件*、常量字符*、大小、loff_t*);
静态结构文件\u操作fops=
{
.read=dev_read,
.open=dev_open,
.write=dev_write,
.release=dev_rls,
};
静态int himodule(无效)
{
t=0;
t=寄存器chrdev(0,“chardevdriver”和fops);
if(t<0)
printk(KERN_警报“设备注册失败”\n);
其他的
printk(KERN_ALERT“设备注册成功”\n);
printk(KERN_警报“主要编号为%d”,t);
返回0;
}
静态void byemodule(void)
{
取消注册(t,“chardevdriver”);
printk(KERN_警报“已成功注销”\n);
}
静态int dev_open(结构inode*inod,结构文件*fil)
{
printk(KERN_警报“在开发打开的内部”);
返回0;
}
静态ssize\u t dev\u read(结构文件*filp,字符*buff,大小长度,loff\u t*off)
{
短计数=0;
while(消息[计数]!=0){
put_用户(msg[count],buff++);
计数++;
}
返回计数;
}
静态ssize_t dev_write(结构文件*filp,常量字符*buff,大小长度,loff_t*off)
{
短计数=0;
printk(内核警报“内部写入”\n);
memset(msg,0100);
printk(KERN_ALERT“透镜尺寸为%zd”,透镜);
而(len>0){
msg[count]=buff[count];
蓝--;
计数++;
}
返回计数;
}
静态int dev_rls(结构inode*inod,结构文件*fil)
{
printk(内核警报“设备关闭”\n);
返回0;
}
模块初始化(himodule);
模块退出(byemodule);

您没有考虑传递到
dev_read
函数的缓冲区大小,因此您可能在
cat
中调用未定义的行为。试试这个:

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;
}
static ssize\u t dev\u read(结构文件*filp,字符*buff,大小长度,loff\u t*off)
{
大小\u t计数=0;
printk(内核警报“内部读取%d\n”,*关闭);
while(msg[count]!=0&&count
。read
函数还应正确处理其
len
off
参数。实现从内存缓冲文件读取的最简单方法是使用
simple\u read\u from\u 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);
}
出于教育目的,您可以检查该助手的代码(在
fs/libfs.c
中定义)


顺便说一句,对于您的
.write
方法,您可以使用
simple\u write\u to\u buffer
助手。

通过正确设置
*off
(my\u read()的第四个参数
可以解决此问题

您需要第一次返回count,第二次返回零

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

这里有一个完整的字符设备文件示例: