template< typename Device, typename Tr, typename Alloc >
bool tmpfstreamTempl<Device,Tr,Alloc>::set_file_mode(int mode)
{
-
+ if (!get_tmp_filename().empty())
+ return I2n::chmod(get_tmp_filename(),mode);
+ else
+ return false;
}
template< typename Device, typename Tr, typename Alloc >
}
template< typename Device, typename Tr, typename Alloc >
-bool tmpfstreamTempl<Device,Tr,Alloc>::move_to(const std::string& targetpath,
+bool tmpfstreamTempl<Device,Tr,Alloc>::move(const std::string& targetpath,
bool overwrite)
{
+ if (get_tmp_filename().empty())
+ return 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);
+ }
+ 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;
+ }
}
}
BOOST_AUTO_TEST_SUITE(TestTmpfstream)
-BOOST_AUTO_TEST_CASE(Tmpfstream)
+BOOST_AUTO_TEST_CASE(Tmpofstream)
{
tmpofstream tmpf("./tmp.XXXXXX");
}
+BOOST_AUTO_TEST_CASE(TmpofstreamUnlink)
+{
+ tmpofstream tmpf("./tmp.XXXXXX");
+
+ BOOST_CHECK_EQUAL( true, tmpf.is_open() );
+
+ Stat stat(tmpf.get_tmp_filename());
+ BOOST_CHECK_EQUAL( true, (bool)stat );
+ BOOST_CHECK_EQUAL( true, stat.is_regular_file() );
+
+ tmpf << "hello world" << endl;
+
+ // keep open but delete file
+ tmpf.unlink();
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ // writing to already deleted file
+ // POSIX explicitly allows this
+ tmpf << "hello world" << endl;
+ tmpf.flush();
+ BOOST_CHECK_EQUAL( true, tmpf.good() );
+
+ // file still gone after closing
+ tmpf.close();
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+}
+
+BOOST_AUTO_TEST_CASE(TmpofstreamMove1)
+{
+ // just to be sure
+ unlink(".foobar");
+
+ tmpofstream tmpf("./tmp.XXXXXX");
+
+ BOOST_CHECK_EQUAL( true, tmpf.is_open() );
+
+ Stat stat(tmpf.get_tmp_filename());
+ BOOST_CHECK_EQUAL( true, (bool)stat );
+ BOOST_CHECK_EQUAL( true, stat.is_regular_file() );
+
+ tmpf << "hello world" << endl;
+ tmpf.flush();
+
+ BOOST_CHECK_EQUAL( true, tmpf.move(".foobar",false) );
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ Stat stat2(".foobar");
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ tmpf.close();
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ stat2.recheck();
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ unlink(".foobar");
+}
+
+BOOST_AUTO_TEST_CASE(TmpofstreamMove2)
+{
+ // just to be sure
+ unlink(".foobar");
+
+ tmpofstream tmpf("./tmp.XXXXXX");
+
+ BOOST_CHECK_EQUAL( true, tmpf.is_open() );
+
+ Stat stat(tmpf.get_tmp_filename());
+ BOOST_CHECK_EQUAL( true, (bool)stat );
+ BOOST_CHECK_EQUAL( true, stat.is_regular_file() );
+
+ tmpf << "hello world" << endl;
+ tmpf.flush();
+
+ BOOST_CHECK_EQUAL( true, tmpf.move(".foobar",true) );
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ Stat stat2(".foobar");
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ tmpf.close();
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ stat2.recheck();
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ unlink(".foobar");
+}
+
+BOOST_AUTO_TEST_CASE(TmpofstreamMoveOverwrite)
+{
+ // prepare other file
+ write_file(".foobar","blah");
+
+ tmpofstream tmpf("./tmp.XXXXXX");
+
+ BOOST_CHECK_EQUAL( true, tmpf.is_open() );
+
+ Stat stat(tmpf.get_tmp_filename());
+ BOOST_CHECK_EQUAL( true, (bool)stat );
+ BOOST_CHECK_EQUAL( true, stat.is_regular_file() );
+
+ tmpf << "hello world" << endl;
+ tmpf.flush();
+
+ // no overwrite fails
+ BOOST_CHECK_EQUAL( false, tmpf.move(".foobar",false) );
+
+ // overwrite succeeds
+ BOOST_CHECK_EQUAL( true, tmpf.move(".foobar",true) );
+
+ stat.recheck();
+ BOOST_CHECK_EQUAL( false, (bool)stat );
+
+ Stat stat2(".foobar");
+ BOOST_CHECK_EQUAL( true, (bool)stat2 );
+
+ tmpf.close();
+
+ unlink(".foobar");
+}
+
BOOST_AUTO_TEST_SUITE_END()