Reputation: 321
When I try to read a char device using:
cat /dev/fifodev
I receive the next message from the terminal
cat: /dev/fifodev: Invalid argument.
I have created the file and gaven it the permissions like this
sudo mknod /dev/fifodev c 251 0
sudo chmod 666 /dev/fifodev
The code of my driver is:
/*
* Called when a process, which already opened the dev file, attempts to
* read from it.
*/
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
char *buffer, /* buffer to fill with data */
size_t length, /* length of the buffer */
loff_t * offset)
{
char aux[BUF_LEN];
printk(KERN_ALERT "Entering into device_read");
if (size_cbuffer_t(buf)<length){
return -EINVAL;
}
remove_items_cbuffer_t (buf,aux, length);
copy_to_user(buffer, aux, length);
printk(KERN_ALERT "Getting out from device_read");
return length;
}
What problem do I have here? Why can't I use cat with the /dev/fifodev file?
Upvotes: 0
Views: 7156
Reputation: 1327
In the function prototype buffer should be mentioned as __user to specify it as userspace pointer. Return of the read method is length of the string read. This functions keeps getting recalled until it returns zero. I think following code will work.
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
char __user *buffer, /* buffer to fill with data */
size_t length, /* length of the buffer */
loff_t * offset)
{
char aux[BUF_LEN];
int byte_to_read,maxbyte;
printk(KERN_ALERT "Entering into device_read");
/*
if (size_cbuffer_t(buf)<length){
return -EINVAL;
}
*/
maxbyte=strlen(buf) - *offset; //considering buf is the pointer where you have data to copy to buffer(userspace)
byte_to_read=maxbyte>length?length:maxbyte;
if(byte_to_read==0)
{
printk(KERN_ALERT "Allready Read\n");
return 0;
}
aux=buf;//as in your code AUX doesn't have anything. i'm supposing you want to copy data to this from buf and then use copy_to_user
remove_items_cbuffer_t (buf,aux, length); //i have no idea why you have used this but i'm sure this wont create any problem
copy_to_user(buffer, aux, length); //this will copy your data to userspace
printk(KERN_ALERT "Getting out from device_read");
return length;
}
Upvotes: 1
Reputation:
Per your comment, the issue you're running into appears to be that your application is requesting to read data into a buffer that is larger than you have data to fill.
You will need to calculate the appropriate amount of data to copy (e.g, the smaller value of length
and size_cbuffer_t(buf)
), and use that value in the place of length
.
Upvotes: 2