On Sat, Jul 18, 2009 at 4:51 PM, Mickael Wolff
Alexander Lamaison a écrit :
I was looking for exactly such a thing just yesterday and was surprised to find that boost::filesystem didn't have one. Here's the function I wrote instead (Windows only) in case it's of any use:
It is not so surprising. The contrary do it to me ;) On Linux, it exists some functions that do the stuff. But the equivalents to GetTempPath Win32 function are considered as security flaws (the man says it !). Because of race conditions.
So they are tmpfile and mkstemp that compute a temporaty name and open the file. Maybe we can write a wrapper around one of them.
But the file will be open !
Yea, the problem is that in linux you generate a temporary file name by specifying a template, something like "filename_XXXX" and the os fills in the XXXX part for you. but a malicious program in the background could create a hard link with the exact same name as the one just generated to, say, your /etc/shadow file which contains the system's encrypted passwords. So you end up opening the /etc/password file. This is made worse by the fact that only in recent kernel versions did it become possible to say "fail the operation if the file already exists". Any portable solution I believe would need to address this by _not_ exposing a function such as std::string generate_temp_file_name(); but rather exposing a function such as boost::iostreams::file_descriptor create_temporary_file(const boost::filesystem::path& directory, boost::filesystem::path& file_name); that opens the file and returns the file name to the caller. It's up to the function to figure out how to do this on each platform. I needed to solve this problem a long time ago on linux, and if I remember correctly what I ended up doing was create a directory with the sticky bit set in the permissions, create the file in that directory, then try to rename the file back to the original directory. rename will always fail if the target exists. I don't remember the details though, I'd have to find the code I wrote that does this.