Checking for Errors (The GNU C Library)

### 2.1 Checking for Errors ¶

Most library functions return a special value to indicate that they have failed. The special value is typically `-1`, a null pointer, or a constant such as `EOF` that is defined for that purpose. But this return value tells you only that an error has occurred. To find out what kind of error it was, you need to look at the error code stored in the variable `errno`. This variable is declared in the header file `errno.h`.

Variable: `volatile int` errno ¶

  The variable `errno` contains the system error number. You can change the value of `errno`.

  Since `errno` is declared `volatile`, it might be changed asynchronously by a signal handler; see Defining Signal Handlers. However, a properly written signal handler saves and restores the value of `errno`, so you generally do not need to worry about this possibility except when writing signal handlers.

  The initial value of `errno` at program startup is zero. In many cases, when a library function encounters an error, it will set `errno` to a non-zero value to indicate what specific error condition occurred. The documentation for each function lists the error conditions that are possible for that function. Not all library functions use this mechanism; some return an error code directly, instead.

  Warning: Many library functions may set `errno` to some meaningless non-zero value even if they did not encounter any errors, and even if they return error codes directly. Therefore, it is usually incorrect to check whether an error occurred by inspecting the value of `errno`. The proper way to check for error is documented for each function.

  Portability Note: ISO C specifies `errno` as a “modifiable lvalue” rather than as a variable, permitting it to be implemented as a macro. For example, its expansion might involve a function call, like `*__errno_location ()`. In fact, that is what it is on GNU/Linux and GNU/Hurd systems. The GNU C Library, on each system, does whatever is right for the particular system.

  There are a few library functions, like `sqrt` and `atan`, that return a perfectly legitimate value in case of an error, but also set `errno`. For these functions, if you want to check to see whether an error occurred, the recommended method is to set `errno` to zero before calling the function, and then check its value afterward.

All the error codes have symbolic names; they are macros defined in `errno.h`. The names start with ‘`E`’ and an upper-case letter or digit; you should consider names of this form to be reserved names. See Reserved Names.

The error code values are all positive integers and are all distinct, so they can be used as labels in a `switch` statement. Your program should not make any other assumptions about the specific values of these symbolic constants. There are two exceptions to this rule:

- The values of `EAGAIN` and `EWOULDBLOCK` are equal on every supported operating system.
- The values of `ENOTSUP` and `EOPNOTSUPP` are equal on some supported operating systems, for example GNU/Linux.

To make your program portable, you should check for both codes and treat them the same.

The value of `errno` doesn’t necessarily have to correspond to any of these macros, since some library functions might return other error codes of their own for other situations. The only values that are guaranteed to be meaningful for a particular library function are the ones that this manual lists for that function.

Except on GNU/Hurd systems, almost any system call can return `EFAULT` if it is given an invalid pointer as an argument. Since this could only happen as a result of a bug in your program, and since it will not happen on GNU/Hurd systems, we have saved space by not mentioning `EFAULT` in the descriptions of individual functions.

In some Unix systems, many system calls can also return `EFAULT` if given as an argument a pointer into the stack, and the kernel for some obscure reason fails in its attempt to extend the stack. If this ever happens, you should probably try using statically or dynamically allocated memory instead of stack memory on that system.