Search code examples
cfileioerrno

When is errno set


In C I know that you can see the errors using errno in errno.h and I have the following code

int FS_copyFile(const char* PathFrom , const char* PathTo) {
    FILE* Source;
    FILE* Target;

    struct stat st;
    stat(PathFrom, &st);

    char SourceFileData[st.st_size];

    Source = fopen(PathFrom , "r");

    if(Source == NULL) {
        return errno;
    }

    Target = fopen(PathTo , "w");

    if(Target == NULL) {
        return errno;
    }

    fgets(SourceFileData, st.st_size + 1, Source); 

    fputs(SourceFileData , Target);

    fclose(Source);
    fclose(Target);
}

But I am unsure when errno is set. Let us say that the file foo.txt that cannot be written to. Will errno be set when opening the file for writing or attempting to write to it?

I have tried looking online but i can't find anything that actually says when errno is set. In which parts of my code will errno be set if an error happens?


Solution

  • The specification for functions in the standard C library is that functions whose documentation says they set errno set errno as documented and that functions whose documentation is silent about errno might set errno to non-zero, even if no error occurs. (This is because the function might call other routines to do some work, and those routines might report an error, after which the parent routine might resolve the error in some way, so it can successfully complete the task its caller requested, but it may leave errno set.) C 2018 7.5 2 says:

    … The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this document.

    Functions other than those in the standard C library may behave differently. For example, on macOS, the fts_read function will clear errno to indicate a tree traversal is complete:

    … If all the members of the hierarchy have been returned, fts_read() returns NULL and sets the external variable errno to 0…

    Will errno be set when opening the file for writing or attempting to write to it?

    The C standard’s specifications for fopen and fwrite do not mention errno, so they may or may not set errno. Specific implementations of these routines might document that they set errno. For example, the macOS documentation for fopen indicates it may fail and set errno due to failures in malloc or open (or equivalent).

    Note that fwrite is typically buffered, so any failures to write to a file might not occur immediately. If not reported by fwrite, they should be reported by fflush or fclose.