Main Content

Misuse of errno

errno incorrectly checked for error conditions

Description

This defect occurs when you check errno for error conditions in situations where checking errno does not guarantee the absence of errors. In some cases, checking errno can lead to false positives.

For instance, you check errno following calls to the functions:

  • fopen: If you follow the ISO® Standard, the function might not set errno on errors.

  • atof: If you follow the ISO Standard, the function does not set errno.

  • signal: The errno value indicates an error only if the function returns the SIG_ERR error indicator.

Risk

The ISO C Standard does not enforce that these functions set errno on errors. Whether the functions set errno or not is implementation-dependent.

To detect errors, if you check errno alone, the validity of this check also becomes implementation-dependent.

In some cases, the errno value indicates an error only if the function returns a specific error indicator. If you check errno before checking the function return value, you can see false positives.

Fix

For information on how to detect errors, see the documentation for that specific function.

Typically, the functions return an out-of-band error indicator to indicate errors. For instance:

  • fopen returns a null pointer if an error occurs.

  • signal returns the SIG_ERR error indicator and sets errno to a positive value. Check errno only after you have checked the function return value.

Examples

expand all

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

#define fatal_error() abort()

const char *temp_filename = "/tmp/demo.txt";

FILE *func()
{
    FILE *fileptr;
    errno = 0;
    fileptr = fopen(temp_filename, "w+b");
    if (errno != 0) {
        if (fileptr != NULL) {
            (void)fclose(fileptr);
        }
        /* Handle error */
        fatal_error();
    }
    return fileptr;
}

In this example, errno is the first variable that is checked after a call to fopen. You might expect that fopen changes errno to a nonzero value if an error occurs. If you run this code with an implementation of fopen that does not set errno on errors, you might miss an error condition. In this situation, fopen can return a null pointer that escapes detection.

Correction — Check Return Value of fopen After Call

One possible correction is to only check the return value of fopen for a null pointer.

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

#define fatal_error() abort()

const char *temp_filename = "/tmp/demo.txt";

FILE *func()
{
    FILE *fileptr;
    fileptr = fopen(temp_filename, "w+b");
    if (fileptr == NULL) { 
        fatal_error();
    }
    return fileptr;
}

Result Information

Group: Programming
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: ERRNO_MISUSE
Impact: High

Version History

Introduced in R2017a