Boost filesystem get_temporary_file()
I cannot find any function in the Boost.Filesystem library to get a temporary filename. There has been some discussion about this functionality on the lists many years ago - did anything come of this? I need a cross-platform way to do this and was hoping boost would provide it :) Thanks -- Craig Craig Henderson http://craighenderson.co.uk/ http://www.craighenderson.co.uk http://www.siteupdatenotification.com
On Thu, 16 Jul 2009 19:33:19 +0100, Craig Henderson wrote:
I cannot find any function in the Boost.Filesystem library to get a temporary filename. There has been some discussion about this functionality on the lists many years ago - did anything come of this? I need a cross-platform way to do this and was hoping boost would provide it :)
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:
wpath TempFilePath()
{
vector
I cannot find any function in the Boost.Filesystem library to get a temporary filename. There has been some discussion about this functionality on the lists many years ago - did anything come of this? I need a cross-platform way to do this and was hoping boost would provide it :)
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:
wpath TempFilePath() { vector
buffer(MAX_PATH); DWORD len = ::GetTempPath(buffer.size(), &buffer[0]); wstring directory(&buffer[0], buffer.size());
if (!GetTempFileName(directory.c_str(), NULL, 0, &buffer[0])) throw boost::system::system_error( ::GetLastError(), boost::system::system_category);
wstring file(&buffer[0], buffer.size());
return wpath(directory) / file; }
Thanks Alex. I have a similar function for Win32 as this is my primary platform. How should this be implemented for Linux with the same semantics and guarantees? Regards -- Craig
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 ! -- Mickaël Wolff aka Lupus Michaelis Racine http://lupusmic.org Blog http://blog.lupusmic.org
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.
participants (4)
-
Alexander Lamaison
-
Craig Henderson
-
Mickael Wolff
-
Zachary Turner