为什么我在尝试“删除”时会收到错误消息;猫;我的char设备驱动程序?
我已经为Linux编写了一个简单的字符设备驱动程序 它是一个简单的消息存储/检索系统,其中消息存储在内核空间中 我应该可以做这样的事情:为什么我在尝试“删除”时会收到错误消息;猫;我的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
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或其他设备,其中并非所有数据一次可用;在这种情况下,aread
将返回任何可用的数据,下一个将被阻止,直到有更多数据