<errno.h> provides errno, a thread-local variable that functions set to indicate why they failed. Common codes: ENOENT (no file), EACCES (permission denied), EINVAL (invalid argument).
Only check errno immediately after a function that failed; successful calls may overwrite it, giving you meaningless noise.
This example checks errno to distinguish different error conditions after failed file operations.
// compile: gcc -o errnoexample errnoexample.c // run: ./errnoexample // description: interpret errno after system call failures #include <errno.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main() { FILE* f = fopen("/nonexistent/file.txt", "r"); if (!f) { printf("fopen failed: %s (errno %d)\n", strerror(errno), errno); } if (access("/etc/shadow", R_OK) < 0) { printf("access denied: %s\n", strerror(errno)); } return 0; }
Error reporting:
errno: thread-local variable holding last error code (set by library functions on error)strerror(code): convert errno value to human-readable stringperror(prefix): print prefix: error message to stderr (from <stdio.h>)Common error codes (POSIX):
ENOENT: no such file or directoryEACCES: permission deniedEINVAL: invalid argumentENOMEM: out of memory (malloc, etc.)EEXIST: file existsEISDIR: is a directory (expected file)ENOTDIR: not a directory (expected directory)EPERM: operation not permittedEAGAIN, EWOULDBLOCK: resource temporarily unavailableEINTR: interrupted system callEBADF: bad file descriptorERANGE: result out of rangeEIO: input/output errorENOSPC: no space left on deviceUsage notes:
#include <errno.h> before using errno