linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR()

IS_ERR宏定义在include/linux/err.h,如下所示:

#define MAX_ERRNO 4095

//判断x是不是在(0xfffff000,0xffffffff)之间,注意这里用unlikely()的用意

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)

//由错误码求指针,-1 -> 0xFFFFFFFF

static inline void *ERR_PTR(long error)  

{  

    return (void *) error;  

}  

//由指针求错误码,0xFFFFFFFF -> -1 ,依次类推

static inline long PTR_ERR(const void *ptr)  

{  

    return (long) ptr;  

}  

//判断x是不是在(0xfffff000,0xffffffff)之间,x是不是一个有效的指针

static inline long IS_ERR(const void *ptr) 
{  

    return IS_ERR_VALUE((unsigned long)ptr);  

    首先要理解内核空间,所有的驱动程序都运行在内核空间,在这有限的空间中,其最后一个 page是专门为错误码保留的,即内核用最后一页捕捉错误。在写设备驱动程序的过程中,涉及到的指针,必然有以下三种情况:

  • 有效指针;
  • NULL,即空指针;
  • 错误指针,或者说无效指针。

    而所谓的错误指针就是指其已经到达了最后一个page。对于32位的系统,内核空间最高地址为0xffffffff,那么最后一个page就是0xfffff000到 0xffffffff(假设4k一个page),这段地址是被保留的。

    IS_ERR()就是用来判断指针是否有错,如果指针并不是指向最后一个page,那么没有问题;如果指针指向了最后一个page,那么说明实际上这不是一个有效的指针,这个指针里保存的实际上是一种错误代码。

    通常很常用的方法就是先用IS_ERR()来判断是否是错误,然后如果是,那么就调用 PTR_ERR()来返回这个错误代码,返回错误码的时候一般加个负号,如-ENOSYS。

    错误码的值在内存中的定义(asm-generic/errno-base.h):

#define EPERM        1  /* Operation not permitted */  

#define ENOENT       2  /* No such file or directory */  

#define ESRCH        3  /* No such process */  

#define EINTR        4  /* Interrupted system call */  

#define EIO       5  /* I/O error */  

#define ENXIO        6  /* No such device or address */  

#define E2BIG        7  /* Argument list too long */  

#define ENOEXEC      8  /* Exec format error */  

#define EBADF        9  /* Bad file number */  

#define ECHILD      10  /* No child processes */  

#define EAGAIN      11  /* Try again */  

#define ENOMEM      12  /* Out of memory */  

#define EACCES      13  /* Permission denied */  

#define EFAULT      14  /* Bad address */  

#define ENOTBLK     15  /* Block device required */  

#define EBUSY       16  /* Device or resource busy */  

#define EEXIST      17  /* File exists */  

#define EXDEV       18  /* Cross-device link */  

#define ENODEV      19  /* No such device */  

#define ENOTDIR     20  /* Not a directory */  

#define EISDIR      21  /* Is a directory */  

#define EINVAL      22  /* Invalid argument */  

#define ENFILE      23  /* File table overflow */  

#define EMFILE      24  /* Too many open files */  

#define ENOTTY      25  /* Not a typewriter */  

#define ETXTBSY     26  /* Text file busy */  

#define EFBIG       27  /* File too large */  

#define ENOSPC      28  /* No space left on device */  

#define ESPIPE      29  /* Illegal seek */  

#define EROFS       30  /* Read-only file system */  

#define EMLINK      31  /* Too many links */  

#define EPIPE       32  /* Broken pipe */  

#define EDOM        33  /* Math argument out of domain of func */  

#define ERANGE      34  /* Math result not representable */ 

转载于:https://www.cnblogs.com/kazuki/p/10620001.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值