Site Tools


wiki:errno.h

Table of Contents

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.

#include <errno.h>
#include <stdio.h>
#include <string.h>
 
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

// compile: gcc -o errdemo errdemo.c
// run: ./errdemo
// description: trigger two different errno values and show strerror output
 
#include <errno.h>
#include <stdio.h>
#include <string.h>
 
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.

wiki/errno.h.md · Last modified: by 127.0.0.1