cat: error de escritura: argumento no válido

cat: error de escritura: argumento no válido

Escribir en un dispositivo de caracteres personalizado usando

gato 123 > /dev/chardev

da

cat: error de escritura: argumento no válido

Cambié los permisos a 666 e incluso lo probé con sudo. Siguen siendo los mismos resultados. También probé el eco de manera similar.

Yo uso Arch Linux 4.8.

Editar: el código del conductor.

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


//Prototypes
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;
    if(Device_Open)
        return -EBUSY;

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

static int device_release(struct inode *inode,struct file *file){
    Device_Open--;
    module_put(THIS_MODULE);
    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){
        put_user(*(msg_Ptr++),buffer++);
        length--;   
        bytes_read++;
    }
    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;
}

module_init(init);
module_exit(cleanup);

Entonces aquí podemos ver que incluso usé una función device_write y la asigné en la estructura fops a .write. Entonces, ¿no se supone que debe aceptar el comando de escritura e imprimir esa declaración en el registro?

Respuesta1

En el kernel, cada controlador proporciona una serie de métodos para las distintas operaciones que se pueden realizar en un archivo: abrir, cerrar, leer, escribir, buscar, ioctl, etc. Estos métodos se almacenan en unstruct file_operations. Para los dispositivos, los métodos los proporciona el controlador que registró ese dispositivo en particular (es decir, esa combinación particular de bloque/carácter, número mayor y número menor).

Un conductor puede implementar sólo algunos de los métodos; Se proporcionan los valores predeterminados. Los valores predeterminados generalmente no hacen nada y devuelven éxito (si es sensato no hacer nada por ese método) o EINVAL (si no hay un valor predeterminado sensato y la falta de un método significa que la característica no es compatible).

"Error de escritura: argumento no válido" significa que el writemétodo del controlador devuelve EINVAL. La explicación más probable es que este controlador no tiene writeningún método. Es bastante habitual que los controladores no admitan ciertas acciones, por ejemplo, algunos controladores solo admiten ioctl y no lectura/escritura, algunos controladores son intrínsecamente unidireccionales (por ejemplo, un dispositivo de entrada) y solo admiten lectura y no escritura, o viceversa.

El “argumento no válido” no tiene nada que ver con los permisos, es lo que el dispositivo puede hacer. Recibirá un error de permiso si no tiene permiso de escritura, pero sí tiene permiso para hablar con el conductor. Es sólo que lo que le estás pidiendo al conductor que haga es algo de lo que no tiene idea.

información relacionada