C errno.h Header

Error handling and reporting functions

⚠️ What is errno.h?

The errno.h header provides error handling capabilities through the errno variable and related functions. It helps identify and handle errors that occur during program execution, especially with system calls and library functions.


#include <errno.h>

int main() {
    FILE *file = fopen("nonexistent.txt", "r");
    if (file == NULL) {
        printf("Error code: %d\n", errno);
        perror("File error");
    }
    return 0;
}
                                    

Sample Output:

Error code: 2
File error: No such file or directory

Key errno.h Features

🔢

errno

Global variable storing error codes

if (errno != 0) { ... }
📢

perror()

Print error message to stderr

perror("Error occurred");
📝

strerror()

Get error message string

char *msg = strerror(errno);
🏷️

Error Codes

Predefined error constants

ENOENT, EACCES, ENOMEM

🔹 Basic Error Handling

Detecting and handling errors in file operations prevents data loss, ensures program reliability, and provides meaningful feedback to users. Always check return values from functions like fopen(), fread(), and fwrite() for NULL or error indicators. The global errno variable provides specific error information. Implement cleanup routines ensuring files close properly and allocated memory is freed. Robust error handling transforms unpredictable failures into controlled, manageable situations. Professional programs implement comprehensive error detection and recovery strategies.

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    FILE *file;
    
    // Reset errno before operation
    errno = 0;
    
    // Try to open a file that doesn't exist
    file = fopen("missing_file.txt", "r");
    
    if (file == NULL) {
        printf("Failed to open file!\n");
        printf("Error number: %d\n", errno);
        printf("Error message: %s\n", strerror(errno));
        
        // Alternative: use perror()
        perror("fopen");
        
        return 1; // Exit with error code
    }
    
    printf("File opened successfully!\n");
    fclose(file);
    
    return 0;
}

Output:

Failed to open file!
Error number: 2
Error message: No such file or directory
fopen: No such file or directory

🔹 Common Error Codes

Understanding different error types including ENOENT, EACCES, and ENOSPC helps diagnose and respond appropriately to various failure conditions in C. Error codes from errno.h provide specific information about what went wrong. ENOENT indicates missing files, EACCES represents permission denied, ENOSPC means insufficient storage. The perror() function displays human-readable error messages. Learning error codes enables you to implement targeted recovery strategies. Comprehensive error understanding significantly improves application reliability and user experience.

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

void demonstrate_error(int error_code, const char* description) {
    errno = error_code;
    printf("Error %d (%s): %s\n", error_code, description, strerror(errno));
}

int main() {
    printf("Common Error Codes:\n\n");
    
    // Simulate different error conditions
    demonstrate_error(ENOENT, "ENOENT");  // No such file or directory
    demonstrate_error(EACCES, "EACCES");  // Permission denied
    demonstrate_error(ENOMEM, "ENOMEM");  // Out of memory
    demonstrate_error(EINVAL, "EINVAL");  // Invalid argument
    demonstrate_error(EIO, "EIO");        // I/O error
    
    // Example: Memory allocation failure simulation
    printf("\nMemory allocation example:\n");
    errno = 0;
    
    // This won't actually fail on most systems, but demonstrates the concept
    void *ptr = malloc(SIZE_MAX);
    if (ptr == NULL && errno != 0) {
        printf("malloc failed: %s\n", strerror(errno));
    } else {
        printf("malloc succeeded (or errno not set)\n");
        if (ptr) free(ptr);
    }
    
    return 0;
}

Sample Output:

Common Error Codes:

Error 2 (ENOENT): No such file or directory
Error 13 (EACCES): Permission denied
Error 12 (ENOMEM): Cannot allocate memory
Error 22 (EINVAL): Invalid argument
Error 5 (EIO): Input/output error

Memory allocation example:
malloc succeeded (or errno not set)

🔹 Error Handling Best Practices

Proper error checking and cleanup procedures prevent resource leaks, data corruption, and ensure graceful failure recovery in production C applications. Always validate function return values and check for NULL pointers before dereferencing. Implement cleanup code ensuring files close and memory releases even when errors occur. Use goto statements strategically for centralized error handling or implement cleanup functions. Document expected error conditions and implement appropriate recovery mechanisms. These practices transform robust error handling into standard programming practice.

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

int safe_file_copy(const char *source, const char *dest) {
    FILE *src = NULL, *dst = NULL;
    char buffer[1024];
    size_t bytes;
    int result = 0;
    
    // Clear errno before starting
    errno = 0;
    
    // Open source file
    src = fopen(source, "rb");
    if (src == NULL) {
        fprintf(stderr, "Cannot open source file '%s': %s\n", 
                source, strerror(errno));
        return -1;
    }
    
    // Open destination file
    dst = fopen(dest, "wb");
    if (dst == NULL) {
        fprintf(stderr, "Cannot create destination file '%s': %s\n", 
                dest, strerror(errno));
        result = -1;
        goto cleanup;
    }
    
    // Copy file contents
    while ((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0) {
        if (fwrite(buffer, 1, bytes, dst) != bytes) {
            fprintf(stderr, "Write error: %s\n", strerror(errno));
            result = -1;
            goto cleanup;
        }
    }
    
    // Check for read errors
    if (ferror(src)) {
        fprintf(stderr, "Read error: %s\n", strerror(errno));
        result = -1;
    }
    
cleanup:
    if (src) fclose(src);
    if (dst) fclose(dst);
    
    return result;
}

int main() {
    if (safe_file_copy("source.txt", "destination.txt") == 0) {
        printf("File copied successfully!\n");
    } else {
        printf("File copy failed!\n");
    }
    
    return 0;
}

Sample Output (if source.txt doesn't exist):

Cannot open source file 'source.txt': No such file or directory
File copy failed!

🧠 Test Your Knowledge

Which function prints error messages to stderr?