免责声明:本文内容摘自《Linux设备驱动开发》一书,作者为John Madieu,译者为袁鹏飞、刘寿永,由人民邮电出版社出版。本文仅为分享知识和讨论之用,非商业用途。书籍版权归原作者及出版社所有。本人及本博客不对因使用或误用本文内容而产生的任何后果负责。请读者尊重版权,合理使用内容。
当返回指针的函数返回错误时,通常返回的是NULL指针。而去检查为什么会返回空指针是没有任何意义的,因为无法准确了解为什么会返回空指针。
为此,内核提供了3个函数 ERR_PTR、IS_ERR 和 PTR_ERR:
void *ERR_PTR(long error);
long IS_ERR(const void *ptr);
long PTR_ERR(const void *ptr);
第一个函数实际上把错误值作为指针返回。假若函数在内存申请失败后要执行语句 return -ENOMEM;
,则必须改为这样的语句:return ERR_PTR(-ENOMEM);
。
第二个函数用于检查返回值是否是指针错误:if (IS_ERR(foo))
。最后一个函数返回实际错误代码:return PTR_ERR(foo);
。以下是一个例子,说明如何使用
ERR_PTR、IS_ERR、PTR_ERR:
- 返回指针的函数
static struct iio_dev *indiodev_setup() {
[...]
struct iio_dev *indio_dev;
indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data));
if (!indio_dev)
return ERR_PTR(-ENOMEM);
[...]
return indio_dev;
}
- 返回错误代码的函数
static int foo_probe([...]) {
[...]
struct iio_dev *my_indio_dev = indiodev_setup();
if (IS_ERR(my_indio_dev))
return PTR_ERR(data->acc_indio_dev);
[...]
}
关于错误处理补充一点,摘录自内核编码风格部分:
如果函数名称是动作或命令式命令,则函数返回的错误代码应该是整数;如果函数名称是一个谓词,则函数应该返回布尔值 succeeded (成功的)。
例如, add work 是一个命令,add_work()函数返回0表示成功,返回-EBUSY表示失败。同样,PCI device present 是谓词,pci_dev_present()
函数如果成功匹配设备,则返回1;否则返回0。