如何在 Linux 设备驱动程序中设置 errno?
Posted
技术标签:
【中文标题】如何在 Linux 设备驱动程序中设置 errno?【英文标题】:How to set errno in Linux device driver? 【发布时间】:2014-08-25 09:31:26 【问题描述】:我正在设计一个 Linux 字符设备驱动程序。我想在 ioctl() 系统调用中发生错误时设置 errno。
long my_own_ioctl(struct file *file, unsigned int req, unsigned long arg)
long ret = 0;
BOOL isErr = FALSE;
// some operation
// ...
if (isErr)
// set errno
// ... <--- What should I do?
ret = -1;
return ret;
我应该怎么做才能做到这一点?提前谢谢你!
请允许我更详细地解释我的申请。
我的设备位于 /dev/myCharDev。我的用户空间应用是这样的:
#define _COMMAND (1)
#define _ERROR_COMMAND_PARAMETER (-1)
int main()
int fd = open("/dev/myCharDec", O_RDONLY);
int errnoCopy;
if (fd)
if (ioctl(fd, _COMMAND, _ERROR_COMMAND_PARAMETER) < 0) // should cause error in ioctl()
errnoCopy = errno;
printf("Oops, error occurred: %s\n", strerr(errnoCopy)); // I want this "errno" printed correctly
close(fd);
return 0;
正如我在上面的 cmets 中提到的,我应该如何在自己的设备驱动程序代码中设置“errno”并使其被用户空间应用程序读取?
【问题讨论】:
【参考方案1】:好问题!
好的,您可以将 errno 视为全局变量(老实说,它是一个 extern int)。 errno 在 errno.h 库中有大量用于错误代码的预定义宏。你可以看看here。其中一些错误代码很可能描述了您要显示的内容。选择正确的,将其设置为您定义的变量,然后(重要!)立即退出!
您可能会问自己,设置 errno 是否是解决问题的正确方法。您始终可以定义 (*int) 并开发自己的错误代码和错误处理机制。 Errno 的目的是显示和解释系统错误。您是否认为您的代码是“系统”的一部分(我可以看到您开发自己的系统调用,所以可能是这种情况)?所以继续用 errno 来解释你的“系统错误”。
编辑(关于问题更新):好的更多信息。正如我所说,errno 是一个外部整数,由内核设置。设置 errno 的值只是系统调用的返回值。然后 Linux 内核通过库 errno.h 解释这个负值。因此,只需通过返回(EBUSY 只是一个示例 - 您可以使用所有预定义的错误类型)您想要从系统调用中获得的错误消息来设置示例错误消息。示例:
return -EBUSY
希望对你有帮助
【讨论】:
我在我的问题中添加了一些解释。errno is an extern int
没有意义。内核和用户模式程序在不同的地址空间中执行。【参考方案2】:
从 ioctl 返回负错误号。 c 库对此进行解释并给出 -1 返回码并将 errno 设置为正错误。例如,您的原始示例会将 errno 设置为 1。
顺便说一句,您在内核中的 ioctl 函数原型看起来是错误的。您使用的是哪个内核版本?
【讨论】:
谢谢!我结合了您和 sestus 的答案并了解我应该做什么。但塞斯图斯的回答更详细。可惜只能接受一个答案。【参考方案3】:if (isErr)
printk(KERN_ALERT "Error %d: your description\n", errno);
ret = errno;
其中,errno
是某个函数的返回值。
您的设备驱动程序应始终为收到的请求返回状态。 建议您始终使用枚举返回码以及正常返回 代码。返回 0 = 通过 1 或 -1 = 失败是含糊的,可能会产生误导。
阅读3.1 Efficient error handling, reporting and recovery:部分了解更多信息
【讨论】:
据我所知,他想生成错误,并相应地设置 errno。你只是读了errno。但是他开发的系统调用默认没有设置errno。他需要设置它。 是的,我问的是在“设备驱动程序”而不是用户空间应用程序中设置errno。以上是关于如何在 Linux 设备驱动程序中设置 errno?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android Studio 中设置支持的设备类型?
什么是Linux系统调用system call?(Linux内核中设置的一组用于实现各种系统功能的子程序)(区别于标准C库函数调用)核心态和用户态的概念中断的概念系统调用号系统调用表