cat: 쓰기 오류: 잘못된 인수

cat: 쓰기 오류: 잘못된 인수

사용자 정의 문자 장치에 쓰기 사용

고양이 123 > /dev/chardev

주어진

cat: 쓰기 오류: 잘못된 인수

권한을 666으로 변경하고 sudo도 사용해 보았습니다. 결과는 여전히 동일합니다. 또한 비슷한 방식으로 에코를 시도했습니다.

저는 아치리눅스 4.8을 사용하고 있습니다.

편집: 드라이버 코드

#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);

여기서 우리는 심지어 device_write 함수를 사용하고 이를 fops 구조의 .write에 할당했음을 볼 수 있습니다. 그러면 write 명령을 수락하고 로그에 해당 명령문을 인쇄해야 하는 것 아닌가요?

답변1

커널에서 각 드라이버는 파일에 대해 열기, 닫기, 읽기, 쓰기, 탐색, ioctl 등 다양한 작업을 수행할 수 있는 일련의 메서드를 제공합니다. 이러한 메소드는struct file_operations. 장치의 경우 이러한 메서드는 특정 장치(즉, 블록/문자, 메이저 번호 및 마이너 번호의 특정 조합)를 등록하는 드라이버에서 제공됩니다.

드라이버는 이러한 메서드 중 일부만 구현할 수 있으며 기본값은 제공됩니다. 기본값은 일반적으로 아무 작업도 수행하지 않고 성공(메서드에 대해 아무것도 수행하지 않는 것이 합리적인 경우) 또는 EINVAL(합리적인 기본값이 없고 누락된 메서드가 해당 기능이 지원되지 않음을 의미하는 경우)을 반환합니다.

"쓰기 오류: 잘못된 인수"는 write드라이버의 메서드가 EINVAL을 반환했음을 의미합니다. 가장 가능성 있는 설명은 운전자에게 write방법이 없다는 것입니다. 드라이버가 특정 작업을 지원하지 않는 것은 매우 일반적입니다. 예를 들어 일부 드라이버는 ioctl만 지원하고 읽기/쓰기는 지원하지 않으며 일부 드라이버는 본질적으로 단방향(예: 입력 장치)이며 읽기만 지원하고 쓰기는 지원하지 않으며 그 반대의 경우도 마찬가지입니다.

"잘못된 매개변수"는 권한과 관련이 없으며 오히려 장치가 수행할 수 있는 작업과 관련이 있습니다. 쓰기 권한은 없지만 드라이버와 대화할 수 있는 권한이 있는 경우 권한 오류가 발생합니다. 그것은 단지 당신이 운전자에게 전혀 개념이 없는 일을 하라고 요구하는 것일 뿐입니다.

관련 정보