improved error reporting of file errors (uses boost.system's error_code). Now permission errors are properly reported when checking files
This commit is contained in:
parent
86d8b54f5b
commit
3cb1369385
|
@ -111,6 +111,9 @@ namespace libtorrent
|
|||
|
||||
boost::shared_ptr<entry> resume_data;
|
||||
|
||||
// the error code from the file operation
|
||||
error_code error;
|
||||
|
||||
// this is called when operation completes
|
||||
boost::function<void(int, disk_io_job const&)> callback;
|
||||
};
|
||||
|
@ -214,6 +217,8 @@ namespace libtorrent
|
|||
typedef boost::recursive_mutex mutex_t;
|
||||
typedef std::list<cached_piece_entry> cache_t;
|
||||
|
||||
bool test_error(disk_io_job& j);
|
||||
|
||||
// cache operations
|
||||
cache_t::iterator find_cached_piece(
|
||||
cache_t& cache, disk_io_job const& j
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2008, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_ERROR_CODE_HPP_INCLUDED
|
||||
#define TORRENT_ERROR_CODE_HPP_INCLUDED
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION < 103500
|
||||
#include <asio/error_code.hpp>
|
||||
#else
|
||||
#include <boost/system/error_code.hpp>
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
#if BOOST_VERSION < 103500
|
||||
typedef asio::error_code error_code;
|
||||
inline asio::error::error_category get_posix_category() { return asio::error::system_category; }
|
||||
#else
|
||||
using boost::system::error_code;
|
||||
inline boost::system::error_category const& get_posix_category()
|
||||
{ return boost::system::get_posix_category(); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
|
@ -102,20 +103,18 @@ namespace libtorrent
|
|||
static const open_mode out;
|
||||
|
||||
file();
|
||||
file(fs::path const& p, open_mode m);
|
||||
file(fs::path const& p, open_mode m, error_code& ec);
|
||||
~file();
|
||||
|
||||
bool open(fs::path const& p, open_mode m);
|
||||
bool open(fs::path const& p, open_mode m, error_code& ec);
|
||||
void close();
|
||||
bool set_size(size_type size);
|
||||
bool set_size(size_type size, error_code& ec);
|
||||
|
||||
size_type write(const char*, size_type num_bytes);
|
||||
size_type read(char*, size_type num_bytes);
|
||||
size_type write(const char*, size_type num_bytes, error_code& ec);
|
||||
size_type read(char*, size_type num_bytes, error_code& ec);
|
||||
|
||||
size_type seek(size_type pos, seek_mode m = begin);
|
||||
size_type tell();
|
||||
|
||||
std::string const& error() const;
|
||||
size_type seek(size_type pos, seek_mode m, error_code& ec);
|
||||
size_type tell(error_code& ec);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace libtorrent
|
|||
file_pool(int size = 40): m_size(size) {}
|
||||
|
||||
boost::shared_ptr<file> open_file(void* st, fs::path const& p
|
||||
, file::open_mode m, std::string& error);
|
||||
, file::open_mode m, error_code& ec);
|
||||
void release(void* st);
|
||||
void release(fs::path const& p);
|
||||
void resize(int size);
|
||||
|
|
|
@ -73,6 +73,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/io.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
@ -94,12 +95,10 @@ namespace libtorrent
|
|||
typedef asio::ip::udp::socket datagram_socket;
|
||||
typedef asio::ip::tcp::acceptor socket_acceptor;
|
||||
typedef asio::io_service io_service;
|
||||
typedef asio::error_code error_code;
|
||||
|
||||
namespace asio = ::asio;
|
||||
typedef asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
|
||||
#else
|
||||
using boost::system::error_code;
|
||||
using boost::asio::ip::tcp;
|
||||
using boost::asio::ip::udp;
|
||||
using boost::asio::async_write;
|
||||
|
|
|
@ -164,17 +164,17 @@ namespace libtorrent
|
|||
// non-zero return value indicates an error
|
||||
virtual bool delete_files() = 0;
|
||||
|
||||
void set_error(std::string const& file, std::string const& msg) const
|
||||
void set_error(boost::filesystem::path const& file, error_code const& ec) const
|
||||
{
|
||||
m_error_file = file;
|
||||
m_error = msg;
|
||||
m_error_file = file.string();
|
||||
m_error = ec;
|
||||
}
|
||||
|
||||
std::string const& error() const { return m_error; }
|
||||
error_code const& error() const { return m_error; }
|
||||
std::string const& error_file() const { return m_error_file; }
|
||||
void clear_error() { m_error.clear(); m_error_file.clear(); }
|
||||
void clear_error() { m_error = error_code(); m_error_file.clear(); }
|
||||
|
||||
mutable std::string m_error;
|
||||
mutable error_code m_error;
|
||||
mutable std::string m_error_file;
|
||||
|
||||
virtual ~storage_interface() {}
|
||||
|
@ -267,7 +267,7 @@ namespace libtorrent
|
|||
|
||||
void mark_failed(int index);
|
||||
|
||||
std::string const& error() const { return m_storage->error(); }
|
||||
error_code const& error() const { return m_storage->error(); }
|
||||
std::string const& error_file() const { return m_storage->error_file(); }
|
||||
void clear_error() { m_storage->clear_error(); }
|
||||
|
||||
|
@ -308,7 +308,8 @@ namespace libtorrent
|
|||
, int offset
|
||||
, int size);
|
||||
|
||||
bool check_one_piece(int& have_piece);
|
||||
// -1=error 0=ok 1=skip
|
||||
int check_one_piece(int& have_piece);
|
||||
int identify_data(
|
||||
const std::vector<char>& piece_data
|
||||
, int current_slot);
|
||||
|
|
|
@ -420,7 +420,7 @@ namespace libtorrent
|
|||
l.unlock();
|
||||
ret += p.storage->read_impl(buf.get(), p.piece, start_block * m_block_size, buffer_size);
|
||||
l.lock();
|
||||
if (!p.storage->error().empty()) { return -1; }
|
||||
if (p.storage->error()) { return -1; }
|
||||
++m_cache_stats.reads;
|
||||
}
|
||||
|
||||
|
@ -440,7 +440,7 @@ namespace libtorrent
|
|||
{
|
||||
l.unlock();
|
||||
ret += p.storage->read_impl(p.blocks[i], p.piece, piece_offset, block_size);
|
||||
if (!p.storage->error().empty()) { return -1; }
|
||||
if (!p.storage->error()) { return -1; }
|
||||
l.lock();
|
||||
++m_cache_stats.reads;
|
||||
}
|
||||
|
@ -735,6 +735,23 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
bool disk_io_thread::test_error(disk_io_job& j)
|
||||
{
|
||||
error_code const& ec = j.storage->error();
|
||||
if (ec)
|
||||
{
|
||||
j.str = ec.message();
|
||||
j.error = ec;
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
#ifndef NDEBUG
|
||||
std::cout << "ERROR: '" << j.str << "' " << j.error_file << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void disk_io_thread::operator()()
|
||||
{
|
||||
for (;;)
|
||||
|
@ -819,17 +836,10 @@ namespace libtorrent
|
|||
}
|
||||
case disk_io_job::read:
|
||||
{
|
||||
std::string const& error_string = j.storage->error();
|
||||
if (!error_string.empty())
|
||||
if (test_error(j))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
std::cout << "ERROR: '" << error_string << "' " << j.error_file << std::endl;
|
||||
#endif
|
||||
j.str = error_string;
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
ret = -1;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " read " << j.buffer_size << std::endl;
|
||||
|
@ -841,7 +851,8 @@ namespace libtorrent
|
|||
if (j.buffer == 0)
|
||||
{
|
||||
ret = -1;
|
||||
j.str = "out of memory";
|
||||
j.error = error_code(ENOMEM, get_posix_category());
|
||||
j.str = j.error.message();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -853,9 +864,7 @@ namespace libtorrent
|
|||
if (ret == -1)
|
||||
{
|
||||
j.buffer = 0;
|
||||
j.str = j.storage->error();
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
test_error(j);
|
||||
break;
|
||||
}
|
||||
else if (ret == -2)
|
||||
|
@ -864,9 +873,7 @@ namespace libtorrent
|
|||
, j.buffer_size);
|
||||
if (ret < 0)
|
||||
{
|
||||
j.str = j.storage->error();
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
test_error(j);
|
||||
break;
|
||||
}
|
||||
++m_cache_stats.blocks_read;
|
||||
|
@ -876,15 +883,8 @@ namespace libtorrent
|
|||
}
|
||||
case disk_io_job::write:
|
||||
{
|
||||
std::string const& error_string = j.storage->error();
|
||||
if (!error_string.empty())
|
||||
if (test_error(j))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
std::cout << "ERROR: '" << error_string << "' " << j.error_file << std::endl;
|
||||
#endif
|
||||
j.str = error_string;
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -936,26 +936,18 @@ namespace libtorrent
|
|||
if (i != m_pieces.end())
|
||||
{
|
||||
flush_and_remove(i, l);
|
||||
std::string const& e = j.storage->error();
|
||||
if (!e.empty())
|
||||
if (test_error(j))
|
||||
{
|
||||
j.str = e;
|
||||
j.error_file = j.storage->error_file();
|
||||
ret = -1;
|
||||
j.storage->clear_error();
|
||||
j.storage->mark_failed(j.piece);
|
||||
break;
|
||||
}
|
||||
}
|
||||
l.unlock();
|
||||
sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
|
||||
std::string const& e = j.storage->error();
|
||||
if (!e.empty())
|
||||
if (test_error(j))
|
||||
{
|
||||
j.str = e;
|
||||
j.error_file = j.storage->error_file();
|
||||
ret = -1;
|
||||
j.storage->clear_error();
|
||||
j.storage->mark_failed(j.piece);
|
||||
break;
|
||||
}
|
||||
|
@ -972,9 +964,7 @@ namespace libtorrent
|
|||
ret = j.storage->move_storage_impl(j.str) ? 1 : 0;
|
||||
if (ret != 0)
|
||||
{
|
||||
j.str = j.storage->error();
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
test_error(j);
|
||||
break;
|
||||
}
|
||||
j.str = j.storage->save_path().string();
|
||||
|
@ -1010,12 +1000,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
ret = j.storage->release_files_impl();
|
||||
if (ret != 0)
|
||||
{
|
||||
j.str = j.storage->error();
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
}
|
||||
if (ret != 0) test_error(j);
|
||||
break;
|
||||
}
|
||||
case disk_io_job::delete_files:
|
||||
|
@ -1051,12 +1036,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
ret = j.storage->delete_files_impl();
|
||||
if (ret != 0)
|
||||
{
|
||||
j.str = j.storage->error();
|
||||
j.error_file = j.storage->error_file();
|
||||
j.storage->clear_error();
|
||||
}
|
||||
if (ret != 0) test_error(j);
|
||||
break;
|
||||
}
|
||||
case disk_io_job::check_fastresume:
|
||||
|
@ -1090,6 +1070,13 @@ namespace libtorrent
|
|||
#endif
|
||||
if (ret != piece_manager::need_full_check) break;
|
||||
}
|
||||
if (test_error(j))
|
||||
{
|
||||
ret = piece_manager::fatal_disk_error;
|
||||
break;
|
||||
}
|
||||
TORRENT_ASSERT(ret != -2 || !j.str.empty());
|
||||
|
||||
// if the check is not done, add it at the end of the job queue
|
||||
if (ret == piece_manager::need_full_check)
|
||||
{
|
||||
|
@ -1133,6 +1120,7 @@ namespace libtorrent
|
|||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
TORRENT_ASSERT(ret != -2 || !j.str.empty());
|
||||
if (handler) m_ios.post(bind(handler, ret, j));
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (std::exception&)
|
||||
|
|
136
src/file.cpp
136
src/file.cpp
|
@ -121,7 +121,7 @@ namespace
|
|||
}
|
||||
}
|
||||
#else
|
||||
std::string utf8_native(std::string const& s)
|
||||
std::string const& utf8_native(std::string const& s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
@ -146,11 +146,11 @@ namespace libtorrent
|
|||
, m_open_mode(0)
|
||||
{}
|
||||
|
||||
impl(fs::path const& path, int mode)
|
||||
impl(fs::path const& path, int mode, error_code& ec)
|
||||
: m_fd(-1)
|
||||
, m_open_mode(0)
|
||||
{
|
||||
open(path, mode);
|
||||
open(path, mode, ec);
|
||||
}
|
||||
|
||||
~impl()
|
||||
|
@ -158,30 +158,33 @@ namespace libtorrent
|
|||
close();
|
||||
}
|
||||
|
||||
bool open(fs::path const& path, int mode)
|
||||
bool open(fs::path const& path, int mode, error_code& ec)
|
||||
{
|
||||
close();
|
||||
#if defined _WIN32 && defined UNICODE
|
||||
std::wstring wpath(safe_convert(path.native_file_string()));
|
||||
m_fd = ::_wopen(
|
||||
wpath.c_str()
|
||||
, map_open_mode(mode));
|
||||
#elif defined _WIN32
|
||||
m_fd = ::_open(
|
||||
utf8_native(path.native_file_string()).c_str()
|
||||
, map_open_mode(mode));
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
||||
const int permissions = _S_IREAD | _S_IWRITE;
|
||||
|
||||
#ifdef defined UNICODE
|
||||
#define open _wopen
|
||||
std::wstring file_path(safe_convert(path.native_file_string()));
|
||||
#else
|
||||
m_fd = ::open(
|
||||
utf8_native(path.native_file_string()).c_str()
|
||||
, map_open_mode(mode));
|
||||
#define open _open
|
||||
std::string const& file_path = path.native_file_string();
|
||||
#endif
|
||||
#else // if not windows
|
||||
const mode_t permissions = S_IRWXU | S_IRGRP | S_IROTH;
|
||||
std::string const& file_path = path.native_file_string();
|
||||
#endif
|
||||
m_fd = ::open(file_path.c_str(), map_open_mode(mode), permissions);
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
#undef open
|
||||
#endif
|
||||
|
||||
if (m_fd == -1)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "open failed: '" << path.native_file_string() << "'. "
|
||||
<< std::strerror(errno);
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
*m_error = msg.str();
|
||||
ec = error_code(errno, get_posix_category());
|
||||
return false;
|
||||
}
|
||||
m_open_mode = mode;
|
||||
|
@ -201,7 +204,7 @@ namespace libtorrent
|
|||
m_open_mode = 0;
|
||||
}
|
||||
|
||||
size_type read(char* buf, size_type num_bytes)
|
||||
size_type read(char* buf, size_type num_bytes, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_open_mode & mode_in);
|
||||
TORRENT_ASSERT(m_fd != -1);
|
||||
|
@ -211,17 +214,11 @@ namespace libtorrent
|
|||
#else
|
||||
size_type ret = ::read(m_fd, buf, num_bytes);
|
||||
#endif
|
||||
if (ret == -1)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "read failed: " << std::strerror(errno);
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
*m_error = msg.str();
|
||||
}
|
||||
if (ret == -1) ec = error_code(errno, get_posix_category());
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_type write(const char* buf, size_type num_bytes)
|
||||
size_type write(const char* buf, size_type num_bytes, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_open_mode & mode_out);
|
||||
TORRENT_ASSERT(m_fd != -1);
|
||||
|
@ -236,34 +233,25 @@ namespace libtorrent
|
|||
#else
|
||||
size_type ret = ::write(m_fd, buf, num_bytes);
|
||||
#endif
|
||||
if (ret == -1)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "write failed: " << std::strerror(errno);
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
*m_error = msg.str();
|
||||
}
|
||||
if (ret == -1) ec = error_code(errno, get_posix_category());
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool set_size(size_type s)
|
||||
bool set_size(size_type s, error_code& ec)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#error file.cpp is for posix systems only. use file_win.cpp on windows
|
||||
#else
|
||||
if (ftruncate(m_fd, s) < 0)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "ftruncate failed: '" << std::strerror(errno);
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
*m_error = msg.str();
|
||||
ec = error_code(errno, get_posix_category());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_type seek(size_type offset, int m = 1)
|
||||
size_type seek(size_type offset, int m, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_open_mode);
|
||||
TORRENT_ASSERT(m_fd != -1);
|
||||
|
@ -278,56 +266,42 @@ namespace libtorrent
|
|||
// For some strange reason this fails
|
||||
// on win32. Use windows specific file
|
||||
// wrapper instead.
|
||||
if (ret == -1)
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "seek failed: '" << std::strerror(errno)
|
||||
<< "' fd: " << m_fd
|
||||
<< " offset: " << offset
|
||||
<< " seekdir: " << seekdir;
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
*m_error = msg.str();
|
||||
return -1;
|
||||
}
|
||||
if (ret < 0) ec = error_code(errno, get_posix_category());
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_type tell()
|
||||
size_type tell(error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_open_mode);
|
||||
TORRENT_ASSERT(m_fd != -1);
|
||||
|
||||
size_type ret;
|
||||
#ifdef _WIN32
|
||||
return _telli64(m_fd);
|
||||
ret = _telli64(m_fd);
|
||||
#else
|
||||
return lseek(m_fd, 0, SEEK_CUR);
|
||||
ret = lseek(m_fd, 0, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string const& error() const
|
||||
{
|
||||
if (!m_error) m_error.reset(new std::string);
|
||||
return *m_error;
|
||||
if (ret < 0) ec = error_code(errno, get_posix_category());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int m_fd;
|
||||
int m_open_mode;
|
||||
mutable boost::scoped_ptr<std::string> m_error;
|
||||
};
|
||||
|
||||
// pimpl forwardings
|
||||
|
||||
file::file() : m_impl(new impl()) {}
|
||||
|
||||
file::file(fs::path const& p, file::open_mode m)
|
||||
: m_impl(new impl(p, m.m_mask))
|
||||
file::file(fs::path const& p, file::open_mode m, error_code& ec)
|
||||
: m_impl(new impl(p, m.m_mask, ec))
|
||||
{}
|
||||
|
||||
file::~file() {}
|
||||
|
||||
bool file::open(fs::path const& p, file::open_mode m)
|
||||
bool file::open(fs::path const& p, file::open_mode m, error_code& ec)
|
||||
{
|
||||
return m_impl->open(p, m.m_mask);
|
||||
return m_impl->open(p, m.m_mask, ec);
|
||||
}
|
||||
|
||||
void file::close()
|
||||
|
@ -335,34 +309,28 @@ namespace libtorrent
|
|||
m_impl->close();
|
||||
}
|
||||
|
||||
size_type file::write(const char* buf, size_type num_bytes)
|
||||
size_type file::write(const char* buf, size_type num_bytes, error_code& ec)
|
||||
{
|
||||
return m_impl->write(buf, num_bytes);
|
||||
return m_impl->write(buf, num_bytes, ec);
|
||||
}
|
||||
|
||||
size_type file::read(char* buf, size_type num_bytes)
|
||||
size_type file::read(char* buf, size_type num_bytes, error_code& ec)
|
||||
{
|
||||
return m_impl->read(buf, num_bytes);
|
||||
return m_impl->read(buf, num_bytes, ec);
|
||||
}
|
||||
|
||||
bool file::set_size(size_type s)
|
||||
bool file::set_size(size_type s, error_code& ec)
|
||||
{
|
||||
return m_impl->set_size(s);
|
||||
return m_impl->set_size(s, ec);
|
||||
}
|
||||
|
||||
size_type file::seek(size_type pos, file::seek_mode m)
|
||||
size_type file::seek(size_type pos, file::seek_mode m, error_code& ec)
|
||||
{
|
||||
return m_impl->seek(pos, m.m_val);
|
||||
return m_impl->seek(pos, m.m_val, ec);
|
||||
}
|
||||
|
||||
size_type file::tell()
|
||||
size_type file::tell(error_code& ec)
|
||||
{
|
||||
return m_impl->tell();
|
||||
return m_impl->tell(ec);
|
||||
}
|
||||
|
||||
std::string const& file::error() const
|
||||
{
|
||||
return m_impl->error();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
*/
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#include "libtorrent/pch.hpp"
|
||||
|
||||
#include "libtorrent/file_pool.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -41,8 +42,38 @@ namespace libtorrent
|
|||
using boost::multi_index::nth_index;
|
||||
using boost::multi_index::get;
|
||||
|
||||
#if BOOST_VERSION >= 103500
|
||||
struct file_pool_error_category : boost::system::error_category
|
||||
{
|
||||
virtual const char* name() const { return "file pool error"; }
|
||||
virtual std::string message(int ev) const
|
||||
{
|
||||
static char const* msgs[] =
|
||||
{ "no error", "torrent file collides with file from another torrent" };
|
||||
if (ev < 0 || ev >= sizeof(msgs)/sizeof(msgs[0]))
|
||||
return "Unknown error";
|
||||
return msgs[ev];
|
||||
}
|
||||
virtual boost::system::error_condition default_error_condition(int ev) const
|
||||
{
|
||||
return boost::system::error_condition(ev, *this);
|
||||
}
|
||||
virtual bool equivalent(int code, boost::system::error_condition const& condition) const
|
||||
{
|
||||
return default_error_condition(code) == condition;
|
||||
}
|
||||
virtual bool equivalent(boost::system::error_code const& code, int condition ) const
|
||||
{
|
||||
return *this == code.category() && code.value() == condition;
|
||||
}
|
||||
};
|
||||
|
||||
file_pool_error_category file_pool_category;
|
||||
|
||||
#endif
|
||||
|
||||
boost::shared_ptr<file> file_pool::open_file(void* st, fs::path const& p
|
||||
, file::open_mode m, std::string& error)
|
||||
, file::open_mode m, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(st != 0);
|
||||
TORRENT_ASSERT(p.is_complete());
|
||||
|
@ -60,8 +91,9 @@ namespace libtorrent
|
|||
{
|
||||
// this means that another instance of the storage
|
||||
// is using the exact same file.
|
||||
error = "torrent uses the same file as another torrent "
|
||||
"(" + p.string() + ")";
|
||||
#if BOOST_VERSION >= 103500
|
||||
ec = error_code(1, file_pool_category);
|
||||
#endif
|
||||
return boost::shared_ptr<file>();
|
||||
}
|
||||
|
||||
|
@ -73,9 +105,8 @@ namespace libtorrent
|
|||
i->file_ptr.reset();
|
||||
TORRENT_ASSERT(e.file_ptr.unique());
|
||||
e.file_ptr->close();
|
||||
if (!e.file_ptr->open(p, m))
|
||||
if (!e.file_ptr->open(p, m, ec))
|
||||
{
|
||||
error = e.file_ptr->error();
|
||||
m_files.erase(i);
|
||||
return boost::shared_ptr<file>();
|
||||
}
|
||||
|
@ -97,17 +128,14 @@ namespace libtorrent
|
|||
lt.erase(i);
|
||||
}
|
||||
lru_file_entry e;
|
||||
e.file_ptr.reset(new file);
|
||||
e.file_ptr.reset(new (std::nothrow)file);
|
||||
if (!e.file_ptr)
|
||||
{
|
||||
error = "no memory";
|
||||
ec = error_code(ENOMEM, get_posix_category());
|
||||
return e.file_ptr;
|
||||
}
|
||||
if (!e.file_ptr->open(p, m))
|
||||
{
|
||||
error = e.file_ptr->error();
|
||||
if (!e.file_ptr->open(p, m, ec))
|
||||
return boost::shared_ptr<file>();
|
||||
}
|
||||
e.mode = m;
|
||||
e.key = st;
|
||||
e.file_path = p;
|
||||
|
|
225
src/storage.cpp
225
src/storage.cpp
|
@ -253,20 +253,20 @@ namespace
|
|||
namespace libtorrent
|
||||
{
|
||||
template <class Path>
|
||||
void recursive_copy(Path const& old_path, Path const& new_path, std::string& error)
|
||||
void recursive_copy(Path const& old_path, Path const& new_path, error_code& ec)
|
||||
{
|
||||
using boost::filesystem::basic_directory_iterator;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
TORRENT_ASSERT(error.empty());
|
||||
TORRENT_ASSERT(!ec);
|
||||
if (is_directory(old_path))
|
||||
{
|
||||
create_directory(new_path);
|
||||
for (basic_directory_iterator<Path> i(old_path), end; i != end; ++i)
|
||||
{
|
||||
recursive_copy(i->path(), new_path / i->leaf(), error);
|
||||
if (!error.empty()) return;
|
||||
recursive_copy(i->path(), new_path / i->leaf(), ec);
|
||||
if (ec) return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -274,7 +274,7 @@ namespace libtorrent
|
|||
copy_file(old_path, new_path);
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (std::exception& e) { error = e.what(); }
|
||||
} catch (std::exception& e) { ec = error_code(errno, get_posix_category()); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -478,6 +478,7 @@ namespace libtorrent
|
|||
|
||||
bool storage::initialize(bool allocate_files)
|
||||
{
|
||||
error_code ec;
|
||||
// first, create all missing directories
|
||||
fs::path last_path;
|
||||
for (file_storage::iterator file_iter = files().begin(),
|
||||
|
@ -508,18 +509,12 @@ namespace libtorrent
|
|||
// the directory exists.
|
||||
if (file_iter->size == 0)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
file(m_save_path / file_iter->path, file::out);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
file(m_save_path / file_iter->path, file::out, ec);
|
||||
if (ec)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), e.what());
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -528,18 +523,22 @@ namespace libtorrent
|
|||
#endif
|
||||
if (allocate_files)
|
||||
{
|
||||
std::string error;
|
||||
error_code ec;
|
||||
boost::shared_ptr<file> f = m_pool.open_file(this
|
||||
, m_save_path / file_iter->path, file::in | file::out
|
||||
, error);
|
||||
if (f && f->error().empty())
|
||||
f->set_size(file_iter->size);
|
||||
, m_save_path / file_iter->path, file::in | file::out, ec);
|
||||
if (ec) set_error(m_save_path / file_iter->path, ec);
|
||||
else if (f)
|
||||
{
|
||||
f->set_size(file_iter->size, ec);
|
||||
if (ec) set_error(m_save_path / file_iter->path, ec);
|
||||
}
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), e.what());
|
||||
set_error(m_save_path / file_iter->path
|
||||
, error_code(errno, get_posix_category()));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -568,6 +567,15 @@ namespace libtorrent
|
|||
{
|
||||
#endif
|
||||
rename(old_path, new_path);
|
||||
/*
|
||||
error_code ec;
|
||||
rename(old_path, new_path, ec);
|
||||
if (ec)
|
||||
{
|
||||
set_error(old_path, ec);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
if (!m_mapped_files)
|
||||
{ m_mapped_files.reset(new file_storage(m_files)); }
|
||||
m_mapped_files->rename_file(index, new_filename);
|
||||
|
@ -575,7 +583,7 @@ namespace libtorrent
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
set_error(old_name.string(), e.what());
|
||||
set_error(old_name, error_code(errno, get_posix_category()));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -595,8 +603,7 @@ namespace libtorrent
|
|||
m_pool.release(this);
|
||||
buffer().swap(m_scratch_buffer);
|
||||
|
||||
int result = 0;
|
||||
std::string error;
|
||||
int error;
|
||||
std::string error_file;
|
||||
|
||||
// delete the files from disk
|
||||
|
@ -619,16 +626,14 @@ namespace libtorrent
|
|||
{ fs::remove(safe_convert(p)); }
|
||||
catch (std::exception& e)
|
||||
{
|
||||
error = e.what();
|
||||
error = errno;
|
||||
error_file = p;
|
||||
result = 1;
|
||||
}
|
||||
#else
|
||||
if (std::remove(p.c_str()) != 0 && errno != ENOENT)
|
||||
{
|
||||
error = std::strerror(errno);
|
||||
error = errno;
|
||||
error_file = p;
|
||||
result = errno;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -644,26 +649,25 @@ namespace libtorrent
|
|||
{ fs::remove(safe_convert(*i)); }
|
||||
catch (std::exception& e)
|
||||
{
|
||||
error = e.what();
|
||||
error = errno;
|
||||
error_file = *i;
|
||||
result = 1;
|
||||
}
|
||||
#else
|
||||
if (std::remove(i->c_str()) != 0 && errno != ENOENT)
|
||||
{
|
||||
error = std::strerror(errno);
|
||||
error = errno;
|
||||
error_file = *i;
|
||||
result = errno;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!error.empty())
|
||||
if (error)
|
||||
{
|
||||
m_error.swap(error);
|
||||
m_error = error_code(error, get_posix_category());
|
||||
m_error_file.swap(error_file);
|
||||
return true;
|
||||
}
|
||||
return result != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool storage::write_resume_data(entry& rd) const
|
||||
|
@ -832,11 +836,11 @@ namespace libtorrent
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::string err;
|
||||
recursive_copy(old_path, new_path, err);
|
||||
if (!err.empty())
|
||||
error_code ec;
|
||||
recursive_copy(old_path, new_path, ec);
|
||||
if (ec)
|
||||
{
|
||||
set_error((m_save_path / files().name()).string(), e.what());
|
||||
set_error(m_save_path / files().name(), ec);
|
||||
return true;
|
||||
}
|
||||
m_save_path = save_path;
|
||||
|
@ -964,30 +968,24 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
int buf_pos = 0;
|
||||
std::string error;
|
||||
error_code ec;
|
||||
boost::shared_ptr<file> in(m_pool.open_file(
|
||||
this, m_save_path / file_iter->path, file::in
|
||||
, error));
|
||||
if (!in)
|
||||
this, m_save_path / file_iter->path, file::in, ec));
|
||||
if (!in || ec)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), error);
|
||||
return -1;
|
||||
}
|
||||
if (!in->error().empty())
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), in->error());
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return -1;
|
||||
}
|
||||
TORRENT_ASSERT(file_offset < file_iter->size);
|
||||
TORRENT_ASSERT(slices[0].offset == file_offset + file_iter->file_base);
|
||||
|
||||
size_type new_pos = in->seek(file_offset + file_iter->file_base);
|
||||
if (new_pos != file_offset + file_iter->file_base)
|
||||
size_type new_pos = in->seek(file_offset + file_iter->file_base, file::begin, ec);
|
||||
if (new_pos != file_offset + file_iter->file_base || ec)
|
||||
{
|
||||
// the file was not big enough
|
||||
if (!fill_zero)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "seek failed");
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return -1;
|
||||
}
|
||||
std::memset(buf + buf_pos, 0, size - buf_pos);
|
||||
|
@ -995,8 +993,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_type in_tell = in->tell();
|
||||
TORRENT_ASSERT(in_tell == file_offset + file_iter->file_base);
|
||||
size_type in_tell = in->tell(ec);
|
||||
TORRENT_ASSERT(in_tell == file_offset + file_iter->file_base && !ec);
|
||||
#endif
|
||||
|
||||
int left_to_read = size;
|
||||
|
@ -1029,15 +1027,15 @@ namespace libtorrent
|
|||
== file_iter->path);
|
||||
#endif
|
||||
|
||||
int actual_read = int(in->read(buf + buf_pos, read_bytes));
|
||||
int actual_read = int(in->read(buf + buf_pos, read_bytes, ec));
|
||||
|
||||
if (read_bytes != actual_read)
|
||||
if (read_bytes != actual_read || ec)
|
||||
{
|
||||
// the file was not big enough
|
||||
if (actual_read > 0) buf_pos += actual_read;
|
||||
if (!fill_zero)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "read failed");
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return -1;
|
||||
}
|
||||
std::memset(buf + buf_pos, 0, size - buf_pos);
|
||||
|
@ -1061,25 +1059,19 @@ namespace libtorrent
|
|||
fs::path path = m_save_path / file_iter->path;
|
||||
|
||||
file_offset = 0;
|
||||
std::string error;
|
||||
in = m_pool.open_file(
|
||||
this, path, file::in, error);
|
||||
if (!in)
|
||||
error_code ec;
|
||||
in = m_pool.open_file( this, path, file::in, ec);
|
||||
if (!in || ec)
|
||||
{
|
||||
set_error(path.string(), error);
|
||||
set_error(path, ec);
|
||||
return -1;
|
||||
}
|
||||
if (!in->error().empty())
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), in->error());
|
||||
return -1;
|
||||
}
|
||||
size_type pos = in->seek(file_iter->file_base);
|
||||
if (pos != file_iter->file_base)
|
||||
size_type pos = in->seek(file_iter->file_base, file::begin, ec);
|
||||
if (pos != file_iter->file_base || ec)
|
||||
{
|
||||
if (!fill_zero)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "seek failed");
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return -1;
|
||||
}
|
||||
std::memset(buf + buf_pos, 0, size - buf_pos);
|
||||
|
@ -1125,28 +1117,23 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
fs::path p(m_save_path / file_iter->path);
|
||||
std::string error;
|
||||
error_code ec;
|
||||
boost::shared_ptr<file> out = m_pool.open_file(
|
||||
this, p, file::out | file::in, error);
|
||||
this, p, file::out | file::in, ec);
|
||||
|
||||
if (!out)
|
||||
if (!out || ec)
|
||||
{
|
||||
set_error(p.string(), error);
|
||||
return -1;
|
||||
}
|
||||
if (!out->error().empty())
|
||||
{
|
||||
set_error(p.string(), out->error());
|
||||
set_error(p, ec);
|
||||
return -1;
|
||||
}
|
||||
TORRENT_ASSERT(file_offset < file_iter->size);
|
||||
TORRENT_ASSERT(slices[0].offset == file_offset + file_iter->file_base);
|
||||
|
||||
size_type pos = out->seek(file_offset + file_iter->file_base);
|
||||
size_type pos = out->seek(file_offset + file_iter->file_base, file::begin, ec);
|
||||
|
||||
if (pos != file_offset + file_iter->file_base)
|
||||
if (pos != file_offset + file_iter->file_base || ec)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "seek failed");
|
||||
set_error(p, ec);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1180,11 +1167,12 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(buf_pos >= 0);
|
||||
TORRENT_ASSERT(write_bytes >= 0);
|
||||
size_type written = out->write(buf + buf_pos, write_bytes);
|
||||
error_code ec;
|
||||
size_type written = out->write(buf + buf_pos, write_bytes, ec);
|
||||
|
||||
if (written != write_bytes)
|
||||
if (written != write_bytes || ec)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "write failed");
|
||||
set_error(m_save_path / file_iter->path, ec);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1205,26 +1193,21 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(file_iter != files().end());
|
||||
fs::path p = m_save_path / file_iter->path;
|
||||
file_offset = 0;
|
||||
std::string error;
|
||||
error_code ec;
|
||||
out = m_pool.open_file(
|
||||
this, p, file::out | file::in, error);
|
||||
this, p, file::out | file::in, ec);
|
||||
|
||||
if (!out)
|
||||
if (!out || ec)
|
||||
{
|
||||
set_error(p.string(), error);
|
||||
return -1;
|
||||
}
|
||||
if (!out->error().empty())
|
||||
{
|
||||
set_error(p.string(), out->error());
|
||||
set_error(p, ec);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_type pos = out->seek(file_iter->file_base);
|
||||
size_type pos = out->seek(file_iter->file_base, file::begin, ec);
|
||||
|
||||
if (pos != file_iter->file_base)
|
||||
if (pos != file_iter->file_base || ec)
|
||||
{
|
||||
set_error((m_save_path / file_iter->path).string(), "seek failed");
|
||||
set_error(p, ec);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1723,6 +1706,7 @@ namespace libtorrent
|
|||
error = f.string();
|
||||
error += ": ";
|
||||
error += e.what();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
#endif
|
||||
|
@ -1762,8 +1746,8 @@ namespace libtorrent
|
|||
{
|
||||
if (m_storage->initialize(m_storage_mode == storage_mode_allocate))
|
||||
{
|
||||
error = m_storage->error();
|
||||
m_storage->clear_error();
|
||||
error = m_storage->error().message();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
m_state = state_finished;
|
||||
|
@ -2021,8 +2005,8 @@ namespace libtorrent
|
|||
if (m_storage->read(&m_scratch_buffer2[0], piece, 0, piece_size)
|
||||
!= piece_size)
|
||||
{
|
||||
error = m_storage->error();
|
||||
m_storage->clear_error();
|
||||
error = m_storage->error().message();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
m_scratch_piece = other_piece;
|
||||
|
@ -2034,8 +2018,8 @@ namespace libtorrent
|
|||
int piece_size = m_files.piece_size(piece);
|
||||
if (m_storage->write(&m_scratch_buffer[0], piece, 0, piece_size) != piece_size)
|
||||
{
|
||||
error = m_storage->error();
|
||||
m_storage->clear_error();
|
||||
error = m_storage->error().message();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
m_piece_to_slot[piece] = piece;
|
||||
|
@ -2075,8 +2059,8 @@ namespace libtorrent
|
|||
int piece_size = m_files.piece_size(other_piece);
|
||||
if (m_storage->read(&m_scratch_buffer[0], piece, 0, piece_size) != piece_size)
|
||||
{
|
||||
error = m_storage->error();
|
||||
m_storage->clear_error();
|
||||
error = m_storage->error().message();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
m_scratch_piece = other_piece;
|
||||
|
@ -2095,9 +2079,16 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(m_state == state_full_check);
|
||||
|
||||
bool skip = check_one_piece(have_piece);
|
||||
int skip = check_one_piece(have_piece);
|
||||
TORRENT_ASSERT(m_current_slot <= m_files.num_pieces());
|
||||
|
||||
if (skip == -1)
|
||||
{
|
||||
error = m_storage->error().message();
|
||||
TORRENT_ASSERT(!error.empty());
|
||||
return fatal_disk_error;
|
||||
}
|
||||
|
||||
if (skip)
|
||||
{
|
||||
clear_error();
|
||||
|
@ -2174,7 +2165,8 @@ namespace libtorrent
|
|||
return need_full_check;
|
||||
}
|
||||
|
||||
bool piece_manager::check_one_piece(int& have_piece)
|
||||
// -1=error 0=ok 1=skip
|
||||
int piece_manager::check_one_piece(int& have_piece)
|
||||
{
|
||||
// ------------------------
|
||||
// DO THE FULL CHECK
|
||||
|
@ -2196,9 +2188,20 @@ namespace libtorrent
|
|||
int num_read = m_storage->read(&m_piece_data[0]
|
||||
, m_current_slot, 0, piece_size);
|
||||
|
||||
if (num_read < 0)
|
||||
{
|
||||
if (m_storage->error()
|
||||
&& m_storage->error() != error_code(ENOENT, get_posix_category()))
|
||||
{
|
||||
std::cerr << m_storage->error().message() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if the file is incomplete, skip the rest of it
|
||||
if (num_read != piece_size)
|
||||
return true;
|
||||
return 1;
|
||||
|
||||
int piece_index = identify_data(m_piece_data, m_current_slot);
|
||||
|
||||
|
@ -2271,7 +2274,7 @@ namespace libtorrent
|
|||
else
|
||||
ret |= m_storage->move_slot(m_current_slot, other_slot);
|
||||
|
||||
if (ret) return true;
|
||||
if (ret) return 1;
|
||||
|
||||
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
|
||||
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
|
||||
|
@ -2304,7 +2307,7 @@ namespace libtorrent
|
|||
ret |= m_storage->move_slot(other_slot, m_current_slot);
|
||||
|
||||
}
|
||||
if (ret) return true;
|
||||
if (ret) return 1;
|
||||
|
||||
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
|
||||
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
|
||||
|
@ -2388,7 +2391,7 @@ namespace libtorrent
|
|||
ret |= m_storage->move_slot(slot2, m_current_slot);
|
||||
}
|
||||
|
||||
if (ret) return true;
|
||||
if (ret) return 1;
|
||||
|
||||
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
|
||||
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
|
||||
|
@ -2411,7 +2414,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
|
||||
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void piece_manager::switch_to_full_mode()
|
||||
|
|
|
@ -211,14 +211,19 @@ namespace libtorrent
|
|||
int load_file(fs::path const& filename, std::vector<char>& v)
|
||||
{
|
||||
file f;
|
||||
if (!f.open(filename, file::in)) return -1;
|
||||
f.seek(0, file::end);
|
||||
size_type s = f.tell();
|
||||
error_code ec;
|
||||
if (!f.open(filename, file::in, ec)) return -1;
|
||||
f.seek(0, file::end, ec);
|
||||
if (ec) return -1;
|
||||
size_type s = f.tell(ec);
|
||||
if (ec) return -1;
|
||||
if (s > 5000000) return -2;
|
||||
v.resize(s);
|
||||
f.seek(0);
|
||||
size_type read = f.read(&v[0], s);
|
||||
f.seek(0, file::begin, ec);
|
||||
if (ec) return -1;
|
||||
size_type read = f.read(&v[0], s, ec);
|
||||
if (read != s) return -3;
|
||||
if (ec) return -3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue