Search code examples
c++cdeprecatedtr24731

Why can't I use fopen?


In the mold of a previous question I asked about the so-called safe library deprecations, I find myself similarly bemused as to why fopen() should be deprecated.

The function takes two C strings, and returns a FILE* ptr, or NULL on failure. Where are the thread-safety problems / string overrun problems? Or is it something else?

Thanks in advance


Solution

  • There is an official ISO/IEC JTC1/SC22/WG14 (C Language) technical report TR24731-1 (bounds checking interfaces) and its rationale available at:

    There is also work towards TR24731-2 (dynamic allocation functions).

    The stated rationale for fopen_s() is:

    6.5.2 File access functions

    When creating a file, the fopen_s and freopen_s functions improve security by protecting the file from unauthorized access by setting its file protection and opening the file with exclusive access.

    The specification says:

    6.5.2.1 The fopen_s function

    Synopsis

    #define __STDC_WANT_LIB_EXT1__ 1
    #include <stdio.h>
    errno_t fopen_s(FILE * restrict * restrict streamptr,
                    const char * restrict filename,
                    const char * restrict mode);
    

    Runtime-constraints

    None of streamptr, filename, or mode shall be a null pointer.

    If there is a runtime-constraint violation, fopen_s does not attempt to open a file. Furthermore, if streamptr is not a null pointer, fopen_s sets *streamptr to the null pointer.

    Description

    The fopen_s function opens the file whose name is the string pointed to by filename, and associates a stream with it.

    The mode string shall be as described for fopen, with the addition that modes starting with the character ’w’ or ’a’ may be preceded by the character ’u’, see below:

    • uw truncate to zero length or create text file for writing, default permissions
    • ua append; open or create text file for writing at end-of-file, default permissions
    • uwb truncate to zero length or create binary file for writing, default permissions
    • uab append; open or create binary file for writing at end-of-file, default permissions
    • uw+ truncate to zero length or create text file for update, default permissions
    • ua+ append; open or create text file for update, writing at end-of-file, default permissions
    • uw+b or uwb+ truncate to zero length or create binary file for update, default permissions
    • ua+b or uab+ append; open or create binary file for update, writing at end-of-file, default permissions

    To the extent that the underlying system supports the concepts, files opened for writing shall be opened with exclusive (also known as non-shared) access. If the file is being created, and the first character of the mode string is not ’u’, to the extent that the underlying system supports it, the file shall have a file permission that prevents other users on the system from accessing the file. If the file is being created and first character of the mode string is ’u’, then by the time the file has been closed, it shall have the system default file access permissions10).

    If the file was opened successfully, then the pointer to FILE pointed to by streamptr will be set to the pointer to the object controlling the opened file. Otherwise, the pointer to FILE pointed to by streamptr will be set to a null pointer.

    Returns

    The fopen_s function returns zero if it opened the file. If it did not open the file or if there was a runtime-constraint violation, fopen_s returns a non-zero value.

    10) These are the same permissions that the file would have been created with by fopen.