fixed rename_file to work when the file hasn't been created yet. Fixed error reporting when rename_file fails. Updates the file in the torrent_handle when filename is updated

This commit is contained in:
Arvid Norberg 2008-09-30 23:37:42 +00:00
parent dd256547a8
commit ef42e8f77c
6 changed files with 99 additions and 19 deletions

View File

@ -93,6 +93,7 @@ namespace libtorrent
~torrent_info();
file_storage const& files() const { return m_files; }
file_storage& files() { return m_files; }
void add_tracker(std::string const& url, int tier = 0);
std::vector<announce_entry> const& trackers() const { return m_urls; }

View File

@ -53,6 +53,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#if BOOST_VERSION >= 103500
#include <boost/system/system_error.hpp>
#endif
#ifdef _MSC_VER
#pragma warning(pop)
@ -581,7 +584,10 @@ namespace libtorrent
try
{
#endif
rename(old_path, new_path);
// if old path doesn't exist, just rename the file
// in our file_storage, so that when it is created
// it will get the new name
if (exists(old_path)) rename(old_path, new_path);
/*
error_code ec;
rename(old_path, new_path, ec);
@ -596,6 +602,13 @@ namespace libtorrent
m_mapped_files->rename_file(index, new_filename);
#ifndef BOOST_NO_EXCEPTIONS
}
#if BOOST_VERSION >= 103500
catch (boost::system::system_error& e)
{
set_error(old_name, e.code());
return true;
}
#endif
catch (std::exception& e)
{
set_error(old_name, error_code(errno, get_posix_category()));
@ -726,15 +739,6 @@ namespace libtorrent
m_file_priority[i] = file_priority->list_int_value_at(i, 1);
}
lazy_entry const* mapped_files = rd.dict_find_list("mapped_files");
if (mapped_files && mapped_files->list_size() == m_files.num_files())
{
if (!m_mapped_files)
{ m_mapped_files.reset(new file_storage(m_files)); }
for (int i = 0; i < m_files.num_files(); ++i)
m_mapped_files->rename_file(i, mapped_files->list_string_value_at(i));
}
std::vector<std::pair<size_type, std::time_t> > file_sizes;
lazy_entry const* file_sizes_ent = rd.dict_find_list("file sizes");
if (file_sizes_ent == 0)

View File

@ -1661,6 +1661,7 @@ namespace libtorrent
{
if (alerts().should_post<file_renamed_alert>())
alerts().post_alert(file_renamed_alert(get_handle(), j.str, j.piece));
m_torrent_file->files().rename_file(j.piece, j.str);
}
else
{
@ -2551,6 +2552,17 @@ namespace libtorrent
< boost::bind(&announce_entry::tier, _2));
}
lazy_entry const* mapped_files = rd.dict_find_list("mapped_files");
if (mapped_files && mapped_files->list_size() == m_torrent_file->num_files())
{
for (int i = 0; i < m_torrent_file->num_files(); ++i)
{
std::string new_filename = mapped_files->list_string_value_at(i);
if (new_filename.empty()) continue;
m_torrent_file->files().rename_file(i, new_filename);
}
}
lazy_entry const* url_list = rd.dict_find_list("url-list");
if (url_list)
{

View File

@ -50,7 +50,8 @@ using boost::filesystem::remove_all;
using boost::filesystem::create_directory;
using namespace libtorrent;
void print_alerts(libtorrent::session& ses, char const* name, bool allow_disconnects, bool allow_no_torrents)
void print_alerts(libtorrent::session& ses, char const* name
, bool allow_disconnects, bool allow_no_torrents, bool allow_failed_fastresume)
{
std::vector<torrent_handle> handles = ses.get_torrents();
TEST_CHECK(!handles.empty() || allow_no_torrents);
@ -70,6 +71,8 @@ void print_alerts(libtorrent::session& ses, char const* name, bool allow_disconn
{
std::cerr << name << ": " << a->message() << "\n";
}
TEST_CHECK(dynamic_cast<fastresume_rejected_alert*>(a.get()) == 0 || allow_failed_fastresume);
TEST_CHECK(dynamic_cast<peer_error_alert*>(a.get()) == 0
|| (!handles.empty() && h.is_seed())
|| a->message() == "connecting to peer"

View File

@ -39,7 +39,8 @@ POSSIBILITY OF SUCH DAMAGE.
void print_alerts(libtorrent::session& ses, char const* name
, bool allow_disconnects = false
, bool allow_no_torrents = false);
, bool allow_no_torrents = false
, bool allow_failed_fastresume = false);
void test_sleep(int millisec);
boost::intrusive_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0, int piece_size = 16 * 1024, int num_pieces = 1024 / 8);

View File

@ -417,7 +417,8 @@ void run_test(path const& test_path)
void test_fastresume()
{
std::cout << "=== test fastresume ===" << std::endl;
std::cout << "\n\n=== test fastresume ===" << std::endl;
remove_all("tmp1");
create_directory("tmp1");
std::ofstream file("tmp1/temporary");
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file);
@ -427,15 +428,15 @@ void test_fastresume()
entry resume;
{
session ses;
ses.set_alert_mask(alert::all_categories);
torrent_handle h = ses.add_torrent(boost::intrusive_ptr<torrent_info>(new torrent_info(*t))
, "tmp1", entry()
, storage_mode_compact);
h.rename_file(0, "testing_renamed_files");
for (int i = 0; i < 10; ++i)
{
print_alerts(ses, "ses");
test_sleep(1000);
torrent_status s = h.status();
if (s.progress == 1.0f)
@ -448,16 +449,15 @@ void test_fastresume()
ses.remove_torrent(h, session::delete_files);
}
TEST_CHECK(!exists("tmp1/temporary"));
TEST_CHECK(resume.dict().find("mapped_files") != resume.dict().end());
resume.print(std::cout);
// make sure the fast resume check fails! since we removed the file
{
session ses;
ses.set_alert_mask(alert::all_categories);
torrent_handle h = ses.add_torrent(t, "tmp1", resume
, storage_mode_compact);
std::auto_ptr<alert> a = ses.pop_alert();
ptime end = time_now() + seconds(20);
while (a.get() == 0 || dynamic_cast<fastresume_rejected_alert*>(a.get()) == 0)
@ -473,10 +473,71 @@ void test_fastresume()
}
TEST_CHECK(dynamic_cast<fastresume_rejected_alert*>(a.get()) != 0);
}
remove_all("tmp1");
}
void test_rename_file_in_fastresume()
{
std::cout << "\n\n=== test rename file in fastresume ===" << std::endl;
remove_all("tmp2");
create_directory("tmp2");
std::ofstream file("tmp2/temporary");
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file);
file.close();
TEST_CHECK(exists("tmp2/temporary"));
entry resume;
{
session ses;
ses.set_alert_mask(alert::all_categories);
torrent_handle h = ses.add_torrent(boost::intrusive_ptr<torrent_info>(new torrent_info(*t))
, "tmp2", entry()
, storage_mode_compact);
h.rename_file(0, "testing_renamed_files");
for (int i = 0; i < 10; ++i)
{
print_alerts(ses, "ses");
test_sleep(1000);
torrent_status s = h.status();
if (s.progress == 1.0f)
{
std::cout << "progress: 1.0f" << std::endl;
break;
}
}
resume = h.write_resume_data();
ses.remove_torrent(h);
}
TEST_CHECK(!exists("tmp2/temporary"));
TEST_CHECK(exists("tmp2/testing_renamed_files"));
TEST_CHECK(resume.dict().find("mapped_files") != resume.dict().end());
resume.print(std::cout);
// make sure the fast resume check succeeds, even though we renamed the file
{
session ses;
ses.set_alert_mask(alert::all_categories);
torrent_handle h = ses.add_torrent(t, "tmp2", resume
, storage_mode_compact);
for (int i = 0; i < 5; ++i)
{
print_alerts(ses, "ses");
test_sleep(1000);
}
torrent_status stat = h.status();
TEST_CHECK(stat.state == torrent_status::seeding);
}
remove_all("tmp2");
}
int test_main()
{
test_fastresume();
test_rename_file_in_fastresume();
std::vector<path> test_paths;
char* env = std::getenv("TORRENT_TEST_PATHS");
if (env == 0)
@ -495,8 +556,6 @@ int test_main()
std::for_each(test_paths.begin(), test_paths.end(), bind(&run_test, _1));
test_fastresume();
return 0;
}