Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a std::ofstream to a temp file?

Okay, mkstemp is the preferred way to create a temp file in POSIX.

But it opens the file and returns an int, which is a file descriptor. From that I can only create a FILE*, but not an std::ofstream, which I would prefer in C++. (Apparently, on AIX and some other systems, you can create an std::ofstream from a file descriptor, but my compiler complains when I try that.)

I know I could get a temp file name with tmpnam and then open my own ofstream with it, but that's apparently unsafe due to race conditions, and results in a compiler warning (g++ v3.4. on Linux):

warning: the use of `tmpnam' is dangerous, better use `mkstemp' 

So, is there any portable way to create an std::ofstream to a temp file?

like image 545
Frank Avatar asked Jan 31 '09 21:01

Frank


1 Answers

I've done this function:

#include <stdlib.h> #include <fstream> #include <iostream> #include <vector>  std::string open_temp(std::string path, std::ofstream& f) {     path += "/XXXXXX";     std::vector<char> dst_path(path.begin(), path.end());     dst_path.push_back('\0');      int fd = mkstemp(&dst_path[0]);     if(fd != -1) {         path.assign(dst_path.begin(), dst_path.end() - 1);         f.open(path.c_str(),                 std::ios_base::trunc | std::ios_base::out);         close(fd);     }     return path; }  int main() {     std::ofstream logfile;     open_temp("/tmp", logfile);     if(logfile.is_open()) {         logfile << "hello, dude" << std::endl;     } } 

You should probably make sure to call umask with a proper file creation mask (I would prefer 0600)- the manpage for mkstemp says that the file mode creation mask is not standardized. It uses the fact that mkstemp modifies its argument to the filename that it uses. So, we open it and close the file it opened (so, to not have it opened twice), being left with a ofstream that is connected to that file.

like image 78
Johannes Schaub - litb Avatar answered Oct 03 '22 02:10

Johannes Schaub - litb