# errno.h When a standard library function or system call fails, it tells you two things: the return value (NULL, -1, or similar) tells you that it failed, and **`errno.h`** tells you why. Without `errno`, you would know something went wrong but not whether the file did not exist, you lacked permission, or the disk was full. `errno` is the variable that carries that reason. ```c #include #include #include FILE *f = fopen("missing.txt", "r"); if (!f) { printf("error %d: %s\n", errno, strerror(errno)); // e.g.: error 2: No such file or directory } ``` `strerror(errno)` converts the code to a human-readable string. `perror("label")` does the same and prints directly to stderr with your prefix attached. The most common codes: ``` EPERM 1 Operation not permitted ENOENT 2 No such file or directory EINTR 4 Interrupted by signal EACCES 13 Permission denied EEXIST 17 File already exists EINVAL 22 Invalid argument ENOSPC 28 No space left on device EAGAIN 11 Try again (resource temporarily unavailable) ERANGE 34 Result too large ``` One rule you must not break: only check `errno` immediately after a function that is documented to set it returns a failure indicator. A successful call is allowed to overwrite `errno` with any value, so checking it after a success gives you meaningless noise. Also, on any POSIX system `errno` is thread-local — a failure in another thread does not corrupt yours. ## Practice ```c // compile: gcc -o errdemo errdemo.c // run: ./errdemo // description: trigger two different errno values and show strerror output #include #include #include int main(void) { FILE *f; f = fopen("/this/path/does/not/exist", "r"); if (!f) fprintf(stderr, "nonexistent: %s\n", strerror(errno)); f = fopen("/etc/shadow", "r"); if (!f) fprintf(stderr, "/etc/shadow: %s\n", strerror(errno)); // successful call; do NOT rely on errno after this f = fopen("/dev/null", "r"); if (f) { fclose(f); printf("opened /dev/null; errno is now %d (stale — ignore it)\n", errno); } return 0; } ``` The first call gives `ENOENT`, the second `EACCES` (or `ENOENT` if `/etc/shadow` does not exist on your system). The third call succeeds and the printed errno value is leftover from before — that is the point of the stale-value warning. When debugging `errno`-related code, always check it before any other library call, not several lines later.