如何在 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 中设置支持的设备类型?

如何以编程方式检查设备是不是在 iOS 中设置振动模式?

如何在 nativescript 中设置方向

什么是Linux系统调用system call?(Linux内核中设置的一组用于实现各种系统功能的子程序)(区别于标准C库函数调用)核心态和用户态的概念中断的概念系统调用号系统调用表

如何在 Linux 中设置不到一秒钟的警报?

linux使用gpiolib中设置输出读取value始终为0,修改哪里可以读取gpio管教值?