我正在设计一个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;
}
正如我在上面的评论中所提到的,如何在我自己的设备驱动程序代码中设置“ errno ”并使其可由用户空间应用程序读取?
答案 0 :(得分:12)
好问题!
好的,您可以将errno视为全局变量(要成为一个非常好的,它是一个extern int)。 errno在errno.h库中有大量用于错误代码的预定义宏。你可以看看here。其中一些错误代码很可能描述了您想要显示的内容。拿起正确的一个,设置它就像它是你定义的变量一样,并且(重要!)立即退出!
如果设置errno是解决问题的正确方法,您可能会问自己。您始终可以定义(* int)并开发自己的错误代码和错误处理机制。 Errno的目的是显示和解释系统错误。你认为你的代码是“系统”的一部分(因为我可以看到你开发自己的系统调用,所以可能就是这种情况)?所以继续使用errno来解释你的“系统错误”。
编辑(问题更新):更多信息。正如我所说,errno是一个extern int并由内核设置。设置errno的值只是系统调用的返回值。 Linux内核然后通过库errno.h解释这个负值。因此,只需通过返回(EBUSY只是一个示例 - 您可以使用所有预定义的错误类型)来设置系统调用所需的错误消息来设置示例错误消息。例如:
return -EBUSY
希望有所帮助
答案 1 :(得分:7)
从ioctl返回负的错误编号。 c库解释这个并给出-1返回码并将errno设置为正误差。例如,您的原始示例将errno设置为1.
另外,你在内核中使用ioctl函数的原型看起来是错误的。您使用的是哪个内核版本?
答案 2 :(得分:-1)
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:部分了解更多信息