In Linux user space programming, functions often return integers with the convention that a return value of 0 indicates success of a call to the function and that different (usually negative) non-zero values are used to indicate different errors. In kernel programming, however, many functions may return pointers instead of integers, which complicates this approach since a pointer may use non-zero values to encode valid memory addresses that are returned as the result of a successful call to a function.
Linux addresses this challenge by exploiting the facts that (1) the upper portions of
the range of valid (virtual) addresses are unused, and (2) the use of negative values to indicate errors will make their higher order bits non-zero whether they're returned as pointers or integers, and then (3) providing a useful macro and inline functions in the
file that can handle different combinations of pointer, integer, and Boolean types, in a
portable manner that works across different hardware architectures:
IS_ERR_VALUE macro checks whether the upper range of a (pointer or integer) value is non-empty (i.e., contains an error value).
ERR_PTR function converts a (
long) integer value into a (
void *) pointer value.
PTR_ERR function converts a (
const void *) pointer value into a (
long) integer value.
IS_ERR function converts a (
const void *) pointer value into an (
unsigned long) integer value, uses the
IS_ERR_VALUE macro to check whether the upper range of the value is non-empty (i.e., contains an error value), and returns a
bool value accordingly.
IS_ERR_OR_NULL function returns a
bool value that is
true if (1) the passed (
const void *) pointer value is 0 or (2) the result of converting it into an (
unsigned long) integer value and then using the
IS_ERR_VALUE macro on it indicates that the upper range of the value is non-empty (i.e., contains an error value).
ERR_CAST function converts a (
const void *) pointer into a
void *) pointer (casting away constness).
PTR_ERR_OR_ZERO function uses the
function to check whether the passed (
const void *) pointer value contains an error, and returns an (
int) integer value that is 0 if it does not, or is the error value obtained by calling the
PTR_ERR function with it if it does.