Writing to a custom character device using

cat 123 > /dev/chardev


cat: write error: Invalid argument

I have changed the permissions to 666 and even tried it with sudo. Still the same results. Also tried echo in similar way

I use Arch linux 4.8.

Edit: The code for the driver

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

static int __init init(void);
static void __exit cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);

#define SUCCESS 0
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices*/
#define BUF_LEN 80 /* Max length of the message from the device */

static int Major; //Major number of the devices
static int Device_Open = 0;

static char msg[BUF_LEN]; //Message given when asked
static char *msg_Ptr;

static struct file_operations fops = {
    .read = device_read,
    .write = device_write,
    .open = device_open,
    .release = device_release

static int __init init(){
    Major = register_chrdev(0,DEVICE_NAME,&fops);
    if(Major < 0){
        printk(KERN_ALERT "Failure in registering the device. %d\n", Major);
        return Major;
    printk(KERN_INFO "%s registered with major %d \n",DEVICE_NAME,Major);
    printk(KERN_INFO "create a device with 'mknod /dev/%s c %d 0'\n",DEVICE_NAME,Major);
    printk(KERN_INFO "Try to cat and echo the file and shit man.\n");
    return SUCCESS;

static void __exit cleanup(){
    unregister_chrdev(Major, DEVICE_NAME);
    printk(KERN_ALERT "Unregistered the device %s i guess? \n"DEVICE_NAME);

static int device_open(struct inode *inode,struct file *file){
    static int counter = 0;
        return -EBUSY;

    sprintf(msg, "I already told you %d times Hello world!\n", counter++);
    msg_Ptr = msg;
    return SUCCESS;

static int device_release(struct inode *inode,struct file *file){
    return 0;

static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset){
    int bytes_read = 0;
    if(*msg_Ptr == 0)
        return 0;
    while(length && *msg_Ptr){
    return bytes_read;

static ssize_t device_write(struct file *filp,const char *buff, size_t len, loff_t *off){
    printk(KERN_ALERT "You cannot write to this device.\n");
    return -EINVAL;


So here we can see that i have even used a device_write function and assigned it in the fops struct to .write. So isn't it supposed to accept write command and print that statement in the log?

  • 3
    You need to show details about the custom chardev. If this is your own source code, I think that makes it a StackOverflow Q, you can flag it for migration.
    – sourcejedi
    Commented Oct 30, 2016 at 18:24

1 Answer 1


In the kernel, each driver provides a series of methods for the various operations that can be performed on a file: open, close, read, write, seek, ioctl, etc. These methods are stored in a struct file_operations. For devices, the methods are provided by the driver that registered that particular device (i.e. that particular combination of block/char, major number and minor number).

A driver may implement only some of the methods; defaults are provided. The defaults generally do nothing and return either success (if it's sensible to do nothing for that method) or EINVAL (if there is no sensible default and the lack of a method means that the feature is not supported).

“Write error: Invalid argument” means that the write method of the driver returns EINVAL. The most likely explanation is that this driver doesn't have a write method at all. It is fairly routine for drivers not to support certain actions, e.g. some drivers only support ioctl and not read/write, some drivers are intrinsically unidirectional (e.g. an input device) and only support read and not write or vice versa.

“Invalid argument” has nothing to do with permissions, it's what the device is able to do. You'd get a permission error if you didn't have write permission, but you do have permission to talk to the driver. It's just that what you're asking the driver to do is something that it has no concept of.

  • Thanks. 1)I did not notice that i used the EINVAL(i copied the code from a book). 2)I was expecting it to print the custom error message like it did in the success on the terminal. But it was infact logging the message. So dmesg did give the error message Commented Oct 31, 2016 at 9:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .