2

I wrote h into driver by doing echo: echo -n h /dev/mydriver

When I do cat /dev/mydriver, myread function is printing h continuously. I wanted to print once. How to do that.

static char m;

static ssize_t myread(struct file *f, char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Read()\n");
    if (copy_to_user(buf, &m, 1) != 0)
        return -EFAULT;
    else
        return 1;
}

static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Write()\n");
    if (copy_from_user(&c, buf + len – 1, 1) != 0)
        return -EFAULT;
    else
        return len;
}
kzs
  • 1,793
  • 3
  • 24
  • 44
  • Because you don't have any "end of file" condition. – Some programmer dude Jan 29 '13 at 08:57
  • Okay. I didn't get like where to put the condition. Can you guide me please. – kzs Jan 29 '13 at 09:01
  • @JoachimPileborg You talking about the behaviour of cat here? Does it reread a file if no EOF is found? – sr01853 Jan 29 '13 at 09:08
  • @Sibrajas The `cat` program reads its input until it gets end-of-file. And since the OPs device never does `cat` will continue forever. Also, `cat` doesn't "reread" anything, the OPs device simply "reads" the same character over and over. – Some programmer dude Jan 29 '13 at 09:10
  • @JoachimPileborg I dont understand this part. ""reads" the same character over and over." but myread does a copy_to_user only once. Sorry if this is a very basic question. – sr01853 Jan 29 '13 at 09:14
  • @Sibrajas Yes it copies once, but since it never returns EOF, it will be called again next time `cat` does a `read, doing the copying again, and again, and again... – Some programmer dude Jan 29 '13 at 09:17
  • @JoachimPileborg Thanks for the cat explanation. I never know this before. – kzs Jan 29 '13 at 09:29

2 Answers2

5

If you want to use standard tools (such as cat) with your custom drivers, do not forget to set offset (*loff_t off) correctly. Your read function should look something like this:

static ssize_t myread(struct file *f, char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Read()\n");

    /* You have just a single char in your buffer, so only 0 offset is valid */
    if(*off > 0)
        return 0; /* End of file */

    if (copy_to_user(buf, &m, 1))
        return -EFAULT;

    *off++;
    return 1;
}
KBart
  • 1,580
  • 10
  • 18
1

You have to think about how you want your device to work... Will what you write to it be available to multiple processes? Or should what you write be removed once it's been read?

The latter is of course easier, and can simple be implemented by clearing the variable m in the myread function. If it's zero, then return zero from the myread function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • static ssize_t myread(struct file *f, char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Read()\n"); if (copy_to_user(buf, &m, 1) != 0) return -EFAULT; else if (m) return 1; else return 0; } Can I do like this.. – kzs Jan 29 '13 at 09:12
  • @zair Please never post code in comments. And what I can decipher from the code you _did_ post, you need to check `m` _first_. Also, you should initialize `m` in case someone tries to read it before there's anything written to it, and also clear it on successful read (i.e. when you return `1`). – Some programmer dude Jan 29 '13 at 09:15