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

2021/8/1 7:08:58

本文主要是介绍linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR(),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

原文地址

linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR()
IS_ERR宏定义在include/linux/err.h,如下所示:
#define MAX_ERRNO 4095
// 判断x是不是在(0xfffff000,0xf fffffff)之间,注意这里用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);   }  
       要想明白IS_ERR(),首先要理解内核空间,所有的驱动程序都运行在内核空间。内核空间虽然很大,但总是有限的。在这有限的空间中,其最后一个page是专门为错误码保留的,即内核用最后一页捕捉错误,一般人不可能用到内核空间最后一个page的指针。因此,在写设备驱动程序的过程中,涉及到的指针,必然有以下三种情况:有效指针;NULL,即空指针;错误指针,或者说无效指针。          而所谓的错误指针就是指其已经到达了最后一个page。比如,对于32位的 系统,内核空间最高地址为0xffffffff,那么最后一个page就是0xfffff000到 0xffffffff(假设4k一个page),这段地址是被保留的。如果你发现你的一个指针指向这个范围中的某个地址,那么你的代码肯定出错了。          IS_ERR()就是用来判断指针是否有错,如果指针并不是指向最后一个page,那么没有问题;如果指针指向了最后一个page,那么说明实际上这不是一个有效的指针,这个指针里保存的实际上是一种错误代码。而通常很常用的方法就是先用IS_ERR()来判断是否是错误,然后如果是,那么就调用PTR_ERR()来返回这个错误代码。
    错误码的值在内存中的定义(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 */  
    如果指针指向了最后一个page,那么说明实际上这不是一个有效的指针。这个指针里保存的实际上是一种错误代码。而通常很常用的方法就是先用IS_ERR()来判断是否是错误,然后如果是,那么就调用PTR_ERR()来返回这个错误代码。返回错误码的时候一般加个负号,如-ENOSYS。

这篇关于linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR()的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程