函数ERR_PTR,PTR_ERR还有IS_ERR理解
2012-02-05 10:21
585 查看
许多的内核函数需要返回一个指针,但是函数的调用可能失败,一般我们处理这样的情形都是返回一个NULL指针,就像malloc或kmalloc在没有获得指定的空间申请时的返回值一样。但是有时我们想知道导致函数失败的原因,但是返回NULL就显得信息不够。因此有些函数返回一个实际的错误编码以便对引起错误的原因做一些处理。很多内核接口通过把错误值编码到一个指针值中来返回错误信息。当处理这样的函数时,判断是否成功调用就不能是简单的和NULL进行比较。为了方便使用这样的类型接口,2.6的内核在linux/err.h中实现了三个内联函数:
#define MAX_ERRNO 4095
#ifndef __ASSEMBLY__
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
static inline void *ERR_PTR(long error)
{
return (void *) error;
}
static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
}
static inline long IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即
这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,
而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,
正好在(0xfffff000,0xffffffff)之间。因此可以用
来判断内核函数的返回值是一个有效的指针,还是一个出错代码。
#define MAX_ERRNO 4095
#ifndef __ASSEMBLY__
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
static inline void *ERR_PTR(long error)
{
return (void *) error;
}
static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
}
static inline long IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即
ptr & 0xfff == 0
这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,
而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,
正好在(0xfffff000,0xffffffff)之间。因此可以用
(unsigned long)ptr > (unsigned long)-1000L
来判断内核函数的返回值是一个有效的指针,还是一个出错代码。
相关文章推荐
- 函数ERR_PTR,PTR_ERR还有IS_ERR理解
- ERR_PTR,PTR_ERR还有IS_ERR函数详解
- ERR_PTR,PTR_ERR还有IS_ERR函数详解
- linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR()
- IS_ERR()、PTR_ERR() and ERR_PTR() in Linux Kernel
- 也谈ERR_PTR,PTR_ERR,IS_ERR
- [linux device driver] Chapter 03:IS_ERR的理解
- IS_ERR 理解
- 解读PTR_ERR,ERR_PTR,IS_ERR
- Linux内核中的IS_ERR()、PTR_ERR()和ERR_PTR()
- 理解Go的错误[err is shadowed during return]
- 解读PTR_ERR,ERR_PTR,IS_ERR
- 对内核源码中IS_ERR的理解
- 解读PTR_ERR,ERR_PTR,IS_ERR
- 重温IS_ERR PTR_ERR ERR_PTR
- IS_ERR PTR_ERR ERR_PTR
- IS_ERR、PTR_ERR、ERR_PTR
- 解读PTR_ERR,ERR_PTR,IS_ERR
- 解读PTR_ERR,ERR_PTR,IS_ERR
- Linux中IS_ERR()函数的理解