Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我在尝试“删除”时会收到错误消息;猫;我的char设备驱动程序?_C_Linux_Linux Device Driver_Chardev - Fatal编程技术网

为什么我在尝试“删除”时会收到错误消息;猫;我的char设备驱动程序?

为什么我在尝试“删除”时会收到错误消息;猫;我的char设备驱动程序?,c,linux,linux-device-driver,chardev,C,Linux,Linux Device Driver,Chardev,我已经为Linux编写了一个简单的字符设备驱动程序 它是一个简单的消息存储/检索系统,其中消息存储在内核空间中 我应该可以做这样的事情: echo "message 1" > /dev/mydevice 然后用 cat /dev/mydevice 消息存储在队列中 当我试图检索我硬编码用于测试的消息(消息为“hello”)时,我得到以下命令行输出: cat /dev/mydevice hellocat: /dev/mydevice: Resource temporarily unava

我已经为Linux编写了一个简单的字符设备驱动程序

它是一个简单的消息存储/检索系统,其中消息存储在内核空间中

我应该可以做这样的事情:

echo "message 1" > /dev/mydevice
然后用

cat /dev/mydevice
消息存储在队列中

当我试图检索我硬编码用于测试的消息(消息为“hello”)时,我得到以下命令行输出:

cat /dev/mydevice
hellocat: /dev/mydevice: Resource temporarily unavailable
因此,我收到了预期的hello消息,但显然我做了一些不太正确的事情

下面是处理设备读取的函数

static ssize_t device_read(struct file *filp, char *buffer,
               size_t length, loff_t * offset) {
  unsigned long result;
  int message_size;
  struct message_list* message = pop_message(&global_message_list);

  if (!message) return -EAGAIN;

  message_size = message -> message_length;

  result = copy_to_user(buffer, message -> message, message_size);

  printk(KERN_ALERT "res: %lu, msg_size: %d, len: %d\n", result, message_size, length);
  if (result == 0) return message_size;
  else return message_size - result;
}

cat
实用程序对每个文件多次调用
read
,直到它达到EOF(即)

这是因为并非所有数据都可以立即获得。如果文件大于
cat
s内部缓冲区,它当然需要多次调用
read
,以获取完整数据。即使
read
返回的字节数小于缓冲区的长度,它也需要再次调用
read
,以防以后有更多数据可用(如果输入是TTY或管道,也可能是这种情况)。因此,您需要返回0,以使
cat
认为它位于文件末尾并停止读取

(有关
cat
工作原理的更多详细信息,您可以查看,然后单击。)

处理此问题的一个简单方法是在每个“真实”消息之后在队列中放置一个长度为零的消息,以便下一个
read
将返回EOF。但是,如果您同时有多个读卡器,这将无法正常工作;在这种情况下,一个读卡器可能读取一条消息,然后另一个读卡器读取EOF,然后第一个读卡器读取另一条消息,因此一个读卡器获取两条消息,另一个读卡器获取零。是否使设备线程安全取决于您和/或您的指导老师。ª

这还表明代码中存在另一个潜在问题,您只能部分处理该问题:如果有一条消息传递到
read
,大于缓冲区,则丢弃其余消息,而不是将其保存到下一次
read
。同样,这可能是一个可接受的短缺,或者不是



我不确定是否有可能使其线程安全;这取决于您对不同读取器的区分程度,而我对内核代码或编写字符设备的了解还不够,无法判断这是否可行。

cat实用程序对每个文件多次调用
read
,直到它达到EOF(即默认值)

这是因为并非所有数据都可以立即获得。如果文件大于
cat
s内部缓冲区,它当然需要多次调用
read
,以获取完整数据。即使
read
返回的字节数小于缓冲区的长度,它也需要再次调用
read
,以防以后有更多数据可用(如果输入是TTY或管道,也可能是这种情况)。因此,您需要返回0,以使
cat
认为它位于文件末尾并停止读取

(有关
cat
工作原理的更多详细信息,您可以查看,然后单击。)

处理此问题的一个简单方法是在每个“真实”消息之后在队列中放置一个长度为零的消息,以便下一个
read
将返回EOF。但是,如果您同时有多个读卡器,这将无法正常工作;在这种情况下,一个读卡器可能读取一条消息,然后另一个读卡器读取EOF,然后第一个读卡器读取另一条消息,因此一个读卡器获取两条消息,另一个读卡器获取零。是否使设备线程安全取决于您和/或您的指导老师。ª

这还表明代码中存在另一个潜在问题,您只能部分处理该问题:如果有一条消息传递到
read
,大于缓冲区,则丢弃其余消息,而不是将其保存到下一次
read
。同样,这可能是一个可接受的短缺,或者不是



我不确定是否有可能使其线程安全;这取决于您对不同读取器的区分程度,我对内核代码或编写字符设备的了解还不够,无法判断这是否可行。

我认为
cat
会一直尝试读取,直到它达到EOF(
read
返回0)。在这种情况下,消息用完后,立即转到
EAGAIN
。尝试在队列中的
“hello”
之后编码一条空消息,看看是否有效?(如果这是实际问题,那可能不是最好的解决方案,但它更容易测试;首先,很难让它以线程安全的方式向每个读卡器只返回一条消息。)在没有更多消息时返回EAGAIN是我任务的一部分要求。我有点困惑如何克服这个问题,因为我需要为EOF返回0。@DanielH,这是否意味着cat会多次调用我的read函数?我认为reads传统上返回读取的字节数。如果将队列硬编码为
“hello”
,那么
,那么第一次读取将得到
hello
,第二次读取将得到长度为0的空字符串,表示EOF,第三次读取将得到EAGAIN。是的,
read
返回读取的字节数。但这可能不是整个文件,原因有二:1。显然,如果传递到
read
的缓冲区小于可读取的字节数,那么您就没有全部内容,需要再次调用
read
来获取其余内容。2.可能您正在读取的文件是管道、TTY或其他设备,其中并非所有数据一次可用;在这种情况下,a
read
将返回任何可用的数据,下一个将被阻止,直到有更多数据