if (get_tmp_filename().empty() || is_unlinked())
return false;
+ bool success=false;
+
if (overwrite)
{
// this overwrites an already existing target without further warning
// other errors possible, see errno
- int res = ::rename( get_tmp_filename().c_str(), targetpath.c_str() );
- return (res == 0);
+ if (::rename( get_tmp_filename().c_str(), targetpath.c_str() ) == 0)
+ success=true;
}
else
{
// fails if the target already exists
// other errors possible, see errno
- int res = ::link( get_tmp_filename().c_str(), targetpath.c_str() );
- if (res != 0)
- return false;
- ::unlink(get_tmp_filename().c_str());
- return true;
+ if (::link( get_tmp_filename().c_str(), targetpath.c_str() ) == 0)
+ {
+ success=true;
+ ::unlink(get_tmp_filename().c_str());
+ }
+ }
+
+ if (success)
+ {
+ // store tmpfilename to allow double-move
+ tmpfilename=targetpath;
}
- // TODO: set tmpfilename to new name to correctly handle double moves
+ return success;
}
template< typename Device, typename Tr, typename Alloc >
unlink(".foobar");
}
+BOOST_AUTO_TEST_CASE(TmpofstreamDoubleMove)
+{
+ // just to be sure
+ unlink(".foobar");
+ unlink(".foobar2");
+
+ tmpofstream tmpf("./tmp.XXXXXX");
+
+ BOOST_CHECK_EQUAL( true, tmpf.is_open() );
+
+ Stat stat(tmpf.get_tmp_filename());
+ BOOST_CHECK_EQUAL( true, (bool)stat );
+
+ tmpf << "hello world" << endl;
+ tmpf.flush();
+
+ BOOST_CHECK_EQUAL( true, tmpf.move(".foobar") );
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ Stat stat2(".foobar");
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ BOOST_CHECK_EQUAL( true, tmpf.move(".foobar2") );
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ stat2.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat2 );
+
+ Stat stat3(".foobar2");
+ BOOST_CHECK_EQUAL( true, (bool)stat3 );
+
+ tmpf.unlink();
+}
+
BOOST_AUTO_TEST_CASE(TmpfstreamReadWrite)
{
tmpfstream tmpf("./tmp.XXXXXX",std::ios_base::out | std::ios_base::in );