ERR_PTR PTR_ERR IS_ERR ERROR

在linux-x.xx/include/uapi/asm-generic/errno-base.h和errno.h里分别定义了返回错误的信息。

errno-base.h:

 1 #ifndef _ASM_GENERIC_ERRNO_BASE_H
 2 #define _ASM_GENERIC_ERRNO_BASE_H
 3 
 4 #define    EPERM         1    /* Operation not permitted */
 5 #define    ENOENT         2    /* No such file or directory */
 6 #define    ESRCH         3    /* No such process */
 7 ......
 8 ......
 9 ......
10 #define    EDOM        33    /* Math argument out of domain of func */
11 #define    ERANGE        34    /* Math result not representable */
12 
13 #endif

errno.h:

 1 #define _ASM_GENERIC_ERRNO_H
 2 
 3 #include <asm-generic/errno-base.h>
 4 
 5 #define EDEADLK         35      /* Resource deadlock would occur */
 6 #define ENAMETOOLONG    36      /* File name too long */
 7 #define ENOLCK          37      /* No record locks available */
 8 ......
 9 ......
10 ......
11 #define ERFKILL         132     /* Operation not possible due to RF-kill */
12 
13 #define EHWPOISON       133     /* Memory page has hardware error */
14 
15 #endif

以上可知错误信息在1~133之间,返回错误会添加-号,故返回-133~-1。

部分函数内部有记录错误的信息并且返回。

对于返回非指针的函数,一般返回-ERROR。对于返回指针的函数,需要把ERROR转化为指针。

ERR_PTR、PTR_ERR和IS_ERR定义在linux-x.xx/include/linux/err.h:

 1 #define MAX_ERRNO    4095
 2 
 3 #ifndef __ASSEMBLY__
 4 EPERM        
 5 #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
 6 ERROR
 7 static inline void * __must_check ERR_PTR(long error)        //把错误转化指针
 8 {
 9     return (void *) error;
10 }
11 
12 static inline long __must_check PTR_ERR(const void *ptr)            //把指针转化错误
13 {
14     return (long) ptr;
15 }
16 
17 static inline long __must_check IS_ERR(const void *ptr)        //判断是否错误指针
18 {
19     return IS_ERR_VALUE((unsigned long)ptr);
20 }
21 
22 static inline long __must_check IS_ERR_OR_NULL(const void *ptr)        //判断空指针或者错误指针
23 {
24     return !ptr || IS_ERR_VALUE((unsigned long)ptr);
25 }

重点关注IS_ERR的实现。首先把指针转化成long,然后和(unsigned long)-4095比较。

对于32位系统,-4095=0xFFFF F001,对于64位系统,-4095=0xFFFF FFFF FFFF F001

对于32位系统,内核从0xFFFF F001 ~ 0xFFFF FFFF是冗余空间,对于64位系统,内核从0xFFFF FFFF FFFF F001 ~ 0xFFFF FFFF FFFF FFFF是冗余空间。

分配任何指针不可能到达这个区域,而错误信息在-133~-1在这个区域,故可判断系统的错误指针,从而判断返回的错误指针。

 

posted @ 2016-07-07 14:15  Kevin_Hwang  阅读(265)  评论(0编辑  收藏  举报