c++filesystemsrace-conditionc++23

Can we implement a facility to safely create temporary files in C++23?


After reading a review of my own code, an answer about boost::filesystem::unique_path, another answer about unique_path and its references, documentation about tmpnam and its Linux man page, and a few other related things, I am under the impression that with C++23, we have all we need to provide a safe implementation of temporary file creation, only using the C++23 standard library.

By safe, I among others mean an implementation that would not have the known safety vulnerabilities of tmpnam and boost::filesystem::unique_path.

For instance, we could implement a class temp_file whose constructor would both generate a 128-bit random file name and open a file of that name located under std::filesystem::temp_directory_path() in exclusive mode (std::ios::noreplace), whose destructor would close the file and delete it, and whose stream member function would return a reference to the opened file's input/output stream.

Could such an implementation, assuming it is correct, be considered as a safe facility to create and use temporary files, or am I missing some important considerations, in which case, what are those considerations?


Solution

  • Nicol Bolas' answer, in combination with comments from user17732522, allow me to compose a self-sufficient answer, rooted in the C++ standard.

    Could such an implementation, assuming it is correct, be considered as a safe facility to create and use temporary files, or am I missing some important considerations, in which case, what are those considerations?

    The C++23 final draft contains:

    enter image description here

    Since we can never guarantee that a separate thread or process will not access the temporary file while it is being created and accessed by the user of the facility, such a facility could not be considered as safe.

    Such lack of guaranteed safety is in fact very general for C++' file streams, but, as user17732522 puts it, "it is just a bit worse for [temporary files], because they may be created in a directory accessible by all users".

    When it comes to alternatives, in the C++ standard, we have tmpfile which does not expose a file name, and hence at least theoretically could be safer, at the cost of using the FILE API instead of std::fstream.

    There are also OS-specific alternatives.