make file open mode flags be an enum class for type-safety

This commit is contained in:
arvidn 2017-05-26 14:49:21 -04:00 committed by Arvid Norberg
parent 77dcc5363f
commit ffaabd846c
22 changed files with 317 additions and 219 deletions

View File

@ -869,7 +869,7 @@ void generate_data(char const* path, torrent_info const& ti)
iovec_t const b = { reinterpret_cast<char*>(piece)
, size_t(std::min(left_in_piece, 0x4000))};
storage_error error;
st->writev(b, i, j, 0, error);
st->writev(b, i, j, open_mode_t::write_only, error);
if (error)
std::fprintf(stderr, "storage error: %s\n", error.ec.message().c_str());
}

View File

@ -51,6 +51,7 @@ nobase_include_HEADERS = \
file_pool.hpp \
file_storage.hpp \
fingerprint.hpp \
flags.hpp \
fwd.hpp \
gzip.hpp \
hasher.hpp \

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/string_view.hpp"
#include "libtorrent/span.hpp"
#include "libtorrent/aux_/storage_utils.hpp"
#include "libtorrent/flags.hpp"
#include "libtorrent/aux_/disable_warnings_push.hpp"
@ -125,77 +126,86 @@ namespace libtorrent {
using file_handle = std::shared_ptr<file>;
// the open mode for files. Used for the file constructor or
// file::open().
enum class open_mode_t : std::uint32_t
{
none = 0,
// open the file for reading only
read_only = 0,
// open the file for writing only
write_only = 1,
// open the file for reading and writing
read_write = 2,
// the mask for the bits determining read or write mode
rw_mask = read_only | write_only | read_write,
// open the file in sparse mode (if supported by the
// filesystem).
sparse = 0x4,
// don't update the access timestamps on the file (if
// supported by the operating system and filesystem).
// this generally improves disk performance.
no_atime = 0x8,
// open the file for random access. This disables read-ahead
// logic
random_access = 0x10,
// prevent the file from being opened by another process
// while it's still being held open by this handle
lock_file = 0x20,
// don't put any pressure on the OS disk cache
// because of access to this file. We expect our
// files to be fairly large, and there is already
// a cache at the bittorrent block level. This
// may improve overall system performance by
// leaving running applications in the page cache
no_cache = 0x40,
// this is only used for readv/writev flags
coalesce_buffers = 0x100,
// when creating a file, set the hidden attribute (windows only)
attribute_hidden = 0x200,
// when creating a file, set the executable attribute
attribute_executable = 0x400,
// the mask of all attribute bits
attribute_mask = attribute_hidden | attribute_executable
};
namespace flags {
template <>
struct enable_flag_operators<open_mode_t> : std::true_type {};
}
using namespace flags;
struct TORRENT_EXTRA_EXPORT file : boost::noncopyable
{
// the open mode for files. Used for the file constructor or
// file::open().
enum open_mode_t : std::uint32_t
{
// open the file for reading only
read_only = 0,
// open the file for writing only
write_only = 1,
// open the file for reading and writing
read_write = 2,
// the mask for the bits determining read or write mode
rw_mask = read_only | write_only | read_write,
// open the file in sparse mode (if supported by the
// filesystem).
sparse = 0x4,
// don't update the access timestamps on the file (if
// supported by the operating system and filesystem).
// this generally improves disk performance.
no_atime = 0x8,
// open the file for random access. This disables read-ahead
// logic
random_access = 0x10,
// prevent the file from being opened by another process
// while it's still being held open by this handle
lock_file = 0x20,
// don't put any pressure on the OS disk cache
// because of access to this file. We expect our
// files to be fairly large, and there is already
// a cache at the bittorrent block level. This
// may improve overall system performance by
// leaving running applications in the page cache
no_cache = 0x40,
// this is only used for readv/writev flags
coalesce_buffers = 0x100,
// when creating a file, set the hidden attribute (windows only)
attribute_hidden = 0x200,
// when creating a file, set the executable attribute
attribute_executable = 0x400,
// the mask of all attribute bits
attribute_mask = attribute_hidden | attribute_executable
};
file();
file(std::string const& p, std::uint32_t m, error_code& ec);
file(std::string const& p, open_mode_t m, error_code& ec);
~file();
bool open(std::string const& p, std::uint32_t m, error_code& ec);
bool open(std::string const& p, open_mode_t m, error_code& ec);
bool is_open() const;
void close();
bool set_size(std::int64_t size, error_code& ec);
std::uint32_t open_mode() const { return m_open_mode; }
open_mode_t open_mode() const { return m_open_mode; }
std::int64_t writev(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, std::uint32_t flags = 0);
, error_code& ec, open_mode_t flags = open_mode_t::none);
std::int64_t readv(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, std::uint32_t flags = 0);
, error_code& ec, open_mode_t flags = open_mode_t::none);
std::int64_t get_size(error_code& ec) const;
@ -209,7 +219,7 @@ namespace libtorrent {
handle_type m_file_handle;
std::uint32_t m_open_mode;
open_mode_t m_open_mode = open_mode_t::none;
#if defined TORRENT_WINDOWS
static bool has_manage_volume_privs;
#endif

View File

@ -64,7 +64,7 @@ namespace libtorrent {
// file_storage ``fs`` opened at save path ``p``. ``m`` is the
// file open mode (see file::open_mode_t).
file_handle open_file(storage_index_t st, std::string const& p
, file_index_t file_index, file_storage const& fs, std::uint32_t m
, file_index_t file_index, file_storage const& fs, open_mode_t m
, error_code& ec);
// release all files belonging to the specified storage_interface (``st``)
// the overload that takes ``file_index`` releases only the file with
@ -111,7 +111,7 @@ namespace libtorrent {
file_handle file_ptr;
time_point const opened{aux::time_now()};
time_point last_use{opened};
std::uint32_t mode = 0;
open_mode_t mode = open_mode_t::none;
};
// maps storage pointer, file index pairs to the

View File

@ -0,0 +1,89 @@
/*
Copyright (c) 2017, 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_FLAGS_HPP_INCLUDED
#define TORRENT_FLAGS_HPP_INCLUDED
// this is based on Anthony William's article:
// https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
#include <type_traits> // for enable_if
namespace libtorrent {
namespace flags {
template <typename E>
struct enable_flag_operators : std::false_type {};
#define ENUM_OPERATOR(op) \
template<typename E> \
constexpr typename std::enable_if<enable_flag_operators<E>::value, E>::type \
operator op (E const lhs, E const rhs) { \
using underlying = typename std::underlying_type<E>::type; \
return static_cast<E>( \
static_cast<underlying>(lhs) op static_cast<underlying>(rhs)); \
} \
\
template<typename E> \
typename std::enable_if<enable_flag_operators<E>::value, E&>::type \
operator op##= (E& lhs, E const rhs) { \
using underlying = typename std::underlying_type<E>::type; \
lhs = static_cast<E>( \
static_cast<underlying>(lhs) op static_cast<underlying>(rhs)); \
return lhs; \
}
ENUM_OPERATOR(|)
ENUM_OPERATOR(&)
ENUM_OPERATOR(^)
template<typename E>
constexpr typename std::enable_if<enable_flag_operators<E>::value, E>::type
operator~ (E const operand) {
using underlying = typename std::underlying_type<E>::type;
return static_cast<E>(~static_cast<underlying>(operand));
}
template<typename E>
constexpr typename std::enable_if<enable_flag_operators<E>::value, bool>::type
test(E const operand) {
using underlying = typename std::underlying_type<E>::type;
return static_cast<underlying>(operand) != 0;
}
#undef ENUM_OPERATOR
} // flags
} // libtorrent
#endif

View File

@ -76,7 +76,7 @@ namespace libtorrent {
private:
void open_file(std::uint32_t mode, error_code& ec);
void open_file(open_mode_t mode, error_code& ec);
void flush_metadata_impl(error_code& ec);
std::string m_path;

View File

@ -208,9 +208,9 @@ namespace libtorrent {
// error. If there's an error, the ``storage_error`` must be filled out
// to represent the error that occurred.
virtual int readv(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) = 0;
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0;
virtual int writev(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) = 0;
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0;
// This function is called when first checking (or re-checking) the
// storage for a torrent. It should return true if any of the files that
@ -398,9 +398,9 @@ namespace libtorrent {
virtual bool tick() override;
int readv(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override;
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override;
int writev(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override;
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override;
// if the files in this storage are mapped, returns the mapped
// file_storage, otherwise returns the original file_storage object.
@ -424,8 +424,8 @@ namespace libtorrent {
mutable stat_cache m_stat_cache;
// helper function to open a file in the file pool with the right mode
file_handle open_file(file_index_t file, std::uint32_t mode, storage_error& ec) const;
file_handle open_file_impl(file_index_t file, std::uint32_t mode, error_code& ec) const;
file_handle open_file(file_index_t file, open_mode_t mode, storage_error& ec) const;
file_handle open_file_impl(file_index_t file, open_mode_t mode, error_code& ec) const;
aux::vector<std::uint8_t, file_index_t> m_file_priority;
std::string m_save_path;

View File

@ -117,12 +117,12 @@ namespace libtorrent {
#endif // DEBUG_DISK_THREAD
std::uint32_t file_flags_for_job(disk_io_job* j
open_mode_t file_flags_for_job(disk_io_job* j
, bool const coalesce_buffers)
{
std::uint32_t ret = 0;
if (!(j->flags & disk_interface::sequential_access)) ret |= file::random_access;
if (coalesce_buffers) ret |= file::coalesce_buffers;
open_mode_t ret = open_mode_t::none;
if (!(j->flags & disk_interface::sequential_access)) ret |= open_mode_t::random_access;
if (coalesce_buffers) ret |= open_mode_t::coalesce_buffers;
return ret;
}
@ -664,8 +664,8 @@ namespace libtorrent {
DLOG("]\n");
#endif
std::uint32_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes)
? file::coalesce_buffers : static_cast<file::open_mode_t>(0);
open_mode_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes)
? open_mode_t::coalesce_buffers : open_mode_t::none;
// issue the actual write operation
auto iov_start = iov;
@ -1232,7 +1232,7 @@ namespace libtorrent {
time_point const start_time = clock_type::now();
std::uint32_t const file_flags = file_flags_for_job(j
open_mode_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_reads));
iovec_t b = {buffer.get(), std::size_t(j->d.io.buffer_size)};
@ -1308,7 +1308,7 @@ namespace libtorrent {
// can remove them. We can now release the cache std::mutex and dive into the
// disk operations.
std::uint32_t const file_flags = file_flags_for_job(j
open_mode_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_reads));
time_point const start_time = clock_type::now();
@ -1467,7 +1467,7 @@ namespace libtorrent {
auto buffer = std::move(boost::get<disk_buffer_holder>(j->argument));
iovec_t const b = { buffer.get(), std::size_t(j->d.io.buffer_size)};
std::uint32_t const file_flags = file_flags_for_job(j
open_mode_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_writes));
m_stats_counters.inc_stats_counter(counters::num_writing_threads, 1);
@ -2155,7 +2155,7 @@ namespace libtorrent {
int const piece_size = j->storage->files().piece_size(j->piece);
int const block_size = m_disk_cache.block_size();
int const blocks_in_piece = (piece_size + block_size - 1) / block_size;
std::uint32_t const file_flags = file_flags_for_job(j
open_mode_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_reads));
iovec_t iov = { m_disk_cache.allocate_buffer("hashing")
@ -2200,7 +2200,7 @@ namespace libtorrent {
status_t disk_io_thread::do_hash(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
{
int const piece_size = j->storage->files().piece_size(j->piece);
std::uint32_t const file_flags = file_flags_for_job(j
open_mode_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_reads));
std::unique_lock<std::mutex> l(m_cache_mutex);

View File

@ -326,10 +326,6 @@ done:
# endif
#endif
static_assert((libtorrent::file::rw_mask & libtorrent::file::sparse) == 0, "internal flags error");
static_assert((libtorrent::file::rw_mask & libtorrent::file::attribute_mask) == 0, "internal flags error");
static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0, "internal flags error");
#if defined TORRENT_WINDOWS && defined UNICODE && !TORRENT_USE_WSTRING
#ifdef _MSC_VER
@ -342,6 +338,10 @@ static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0
namespace libtorrent {
static_assert((open_mode_t::rw_mask & open_mode_t::sparse) == open_mode_t::none, "internal flags error");
static_assert((open_mode_t::rw_mask & open_mode_t::attribute_mask) == open_mode_t::none, "internal flags error");
static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t::none, "internal flags error");
directory::directory(std::string const& path, error_code& ec)
: m_done(false)
{
@ -505,14 +505,11 @@ namespace libtorrent {
bool file::has_manage_volume_privs = get_manage_volume_privs();
#endif
file::file()
: m_file_handle(INVALID_HANDLE_VALUE)
, m_open_mode(0)
file::file() : m_file_handle(INVALID_HANDLE_VALUE)
{}
file::file(std::string const& path, std::uint32_t const mode, error_code& ec)
file::file(std::string const& path, open_mode_t const mode, error_code& ec)
: m_file_handle(INVALID_HANDLE_VALUE)
, m_open_mode(0)
{
// the return value is not important, since the
// error code contains the same information
@ -524,20 +521,20 @@ namespace libtorrent {
close();
}
bool file::open(std::string const& path, std::uint32_t mode, error_code& ec)
bool file::open(std::string const& path, open_mode_t mode, error_code& ec)
{
close();
native_path_string file_path = convert_to_native_path_string(path);
#ifdef TORRENT_WINDOWS
struct open_mode_t
struct win_open_mode_t
{
DWORD rw_mode;
DWORD create_mode;
};
static const open_mode_t mode_array[] =
static std::array<win_open_mode_t, 3> const mode_array{
{
// read_only
{GENERIC_READ, OPEN_EXISTING},
@ -545,15 +542,15 @@ namespace libtorrent {
{GENERIC_WRITE, OPEN_ALWAYS},
// read_write
{GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS},
};
}};
static const DWORD attrib_array[] =
static std::array<DWORD, 4> const attrib_array{
{
FILE_ATTRIBUTE_NORMAL, // no attrib
FILE_ATTRIBUTE_HIDDEN, // hidden
FILE_ATTRIBUTE_NORMAL, // executable
FILE_ATTRIBUTE_HIDDEN, // hidden + executable
};
}};
#if TORRENT_USE_WSTRING
#define CreateFile_ CreateFileW
@ -561,21 +558,21 @@ namespace libtorrent {
#define CreateFile_ CreateFileA
#endif
TORRENT_ASSERT((mode & rw_mask) < sizeof(mode_array)/sizeof(mode_array[0]));
open_mode_t const& m = mode_array[mode & rw_mask];
DWORD a = attrib_array[(mode & attribute_mask) >> 12];
TORRENT_ASSERT(static_cast<std::size_t>(mode & open_mode_t::rw_mask) < mode_array.size());
win_open_mode_t const& m = mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)];
DWORD a = attrib_array[static_cast<std::size_t>(mode & open_mode_t::attribute_mask) >> 12];
// one might think it's a good idea to pass in FILE_FLAG_RANDOM_ACCESS. It
// turns out that it isn't. That flag will break your operating system:
// http://support.microsoft.com/kb/2549369
DWORD flags = ((mode & random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN)
DWORD const flags = (test(mode & open_mode_t::random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN)
| (a ? a : FILE_ATTRIBUTE_NORMAL)
| FILE_FLAG_OVERLAPPED
| ((mode & no_cache) ? FILE_FLAG_WRITE_THROUGH : 0);
| (test(mode & open_mode_t::no_cache) ? FILE_FLAG_WRITE_THROUGH : 0);
handle_type handle = CreateFile_(file_path.c_str(), m.rw_mode
, (mode & lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE
, test(mode & open_mode_t::lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE
, 0, m.create_mode, flags, 0);
#undef CreateFile_
@ -591,7 +588,8 @@ namespace libtorrent {
// try to make the file sparse if supported
// only set this flag if the file is opened for writing
if ((mode & file::sparse) && (mode & rw_mask) != read_only)
if (test(mode & open_mode_t::sparse)
&& (mode & open_mode_t::rw_mask) != open_mode_t::read_only)
{
DWORD temp;
overlapped_t ol;
@ -609,7 +607,7 @@ namespace libtorrent {
| S_IRGRP | S_IWGRP
| S_IROTH | S_IWOTH;
if (mode & attribute_executable)
if (test(mode & open_mode_t::attribute_executable))
permissions |= S_IXGRP | S_IXOTH | S_IXUSR;
#ifdef O_BINARY
static const int mode_array[] = {O_RDONLY | O_BINARY, O_WRONLY | O_CREAT | O_BINARY, O_RDWR | O_CREAT | O_BINARY};
@ -619,26 +617,27 @@ namespace libtorrent {
int open_mode = 0
#ifdef O_NOATIME
| ((mode & no_atime) ? O_NOATIME : 0)
| (test(mode & open_mode_t::no_atime) ? O_NOATIME : 0)
#endif
#ifdef O_SYNC
| ((mode & no_cache) ? O_SYNC : 0)
| (test(mode & open_mode_t::no_cache) ? O_SYNC : 0)
#endif
;
handle_type handle = ::open(file_path.c_str()
, mode_array[mode & rw_mask] | open_mode
, mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)] | open_mode
, permissions);
#ifdef O_NOATIME
// O_NOATIME is not allowed for files we don't own
// so, if we get EPERM when we try to open with it
// try again without O_NOATIME
if (handle == -1 && (mode & no_atime) && errno == EPERM)
if (handle == -1 && test(mode & open_mode_t::no_atime) && errno == EPERM)
{
mode &= ~no_atime;
mode &= ~open_mode_t::no_atime;
open_mode &= ~O_NOATIME;
handle = ::open(file_path.c_str(), mode_array[mode & rw_mask] | open_mode
handle = ::open(file_path.c_str()
, mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)] | open_mode
, permissions);
}
#endif
@ -659,7 +658,7 @@ namespace libtorrent {
#ifdef DIRECTIO_ON
// for solaris
if (mode & no_cache)
if (test(mode & open_mode_t::no_cache))
{
int yes = 1;
directio(native_handle(), DIRECTIO_ON);
@ -668,7 +667,7 @@ namespace libtorrent {
#ifdef F_NOCACHE
// for BSD/Mac
if (mode & no_cache)
if (test(mode & open_mode_t::no_cache))
{
int yes = 1;
fcntl(native_handle(), F_NOCACHE, &yes);
@ -681,7 +680,7 @@ namespace libtorrent {
#endif
#ifdef POSIX_FADV_RANDOM
if (mode & random_access)
if (test(mode & open_mode_t::random_access))
{
// disable read-ahead
posix_fadvise(native_handle(), 0, 0, POSIX_FADV_RANDOM);
@ -758,9 +757,9 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
// if this file is open for writing, has the sparse
// flag set, but there are no sparse regions, unset
// the flag
std::uint32_t rw_mode = m_open_mode & rw_mask;
if ((rw_mode != read_only)
&& (m_open_mode & sparse)
open_mode_t const rw_mode = m_open_mode & open_mode_t::rw_mask;
if ((rw_mode != open_mode_t::read_only)
&& test(m_open_mode & open_mode_t::sparse)
&& !is_sparse(native_handle()))
{
overlapped_t ol;
@ -791,7 +790,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
m_file_handle = INVALID_HANDLE_VALUE;
m_open_mode = 0;
m_open_mode = open_mode_t::none;
}
namespace {
@ -974,7 +973,7 @@ namespace {
// this has to be thread safe and atomic. i.e. on posix systems it has to be
// turned into a series of pread() calls
std::int64_t file::readv(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, std::uint32_t flags)
, error_code& ec, open_mode_t flags)
{
if (m_file_handle == INVALID_HANDLE_VALUE)
{
@ -985,7 +984,8 @@ namespace {
#endif
return -1;
}
TORRENT_ASSERT((m_open_mode & rw_mask) == read_only || (m_open_mode & rw_mask) == read_write);
TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_only
|| (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write);
TORRENT_ASSERT(!bufs.empty());
TORRENT_ASSERT(is_open());
@ -997,16 +997,16 @@ namespace {
// there's no point in coalescing single buffer writes
if (bufs.size() == 1)
{
flags &= ~file::coalesce_buffers;
flags &= ~open_mode_t::coalesce_buffers;
}
iovec_t tmp;
span<iovec_t const> tmp_bufs = bufs;
if ((flags & file::coalesce_buffers))
if (test(flags & open_mode_t::coalesce_buffers))
{
if (!coalesce_read_buffers(tmp_bufs, tmp))
// ok, that failed, don't coalesce this read
flags &= ~file::coalesce_buffers;
flags &= ~open_mode_t::coalesce_buffers;
}
#if TORRENT_USE_PREAD
@ -1015,7 +1015,7 @@ namespace {
std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec);
#endif
if ((flags & file::coalesce_buffers))
if (test(flags & open_mode_t::coalesce_buffers))
coalesce_read_buffers_end(bufs
, tmp.data(), !ec);
@ -1027,7 +1027,7 @@ namespace {
// that means, on posix this has to be turned into a series of
// pwrite() calls
std::int64_t file::writev(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, std::uint32_t flags)
, error_code& ec, open_mode_t flags)
{
if (m_file_handle == INVALID_HANDLE_VALUE)
{
@ -1038,7 +1038,8 @@ namespace {
#endif
return -1;
}
TORRENT_ASSERT((m_open_mode & rw_mask) == write_only || (m_open_mode & rw_mask) == read_write);
TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::write_only
|| (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write);
TORRENT_ASSERT(!bufs.empty());
TORRENT_ASSERT(is_open());
@ -1053,15 +1054,15 @@ namespace {
// there's no point in coalescing single buffer writes
if (bufs.size() == 1)
{
flags &= ~file::coalesce_buffers;
flags &= ~open_mode_t::coalesce_buffers;
}
iovec_t tmp;
if (flags & file::coalesce_buffers)
if (test(flags & open_mode_t::coalesce_buffers))
{
if (!coalesce_write_buffers(bufs, tmp))
// ok, that failed, don't coalesce writes
flags &= ~file::coalesce_buffers;
flags &= ~open_mode_t::coalesce_buffers;
}
#if TORRENT_USE_PREAD
@ -1070,14 +1071,14 @@ namespace {
std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec);
#endif
if (flags & file::coalesce_buffers)
if (test(flags & open_mode_t::coalesce_buffers))
delete[] tmp.data();
#endif
#if TORRENT_USE_FDATASYNC \
&& !defined F_NOCACHE && \
!defined DIRECTIO_ON
if (m_open_mode & no_cache)
if (test(m_open_mode & open_mode_t::no_cache))
{
if (fdatasync(native_handle()) != 0
&& errno != EINVAL
@ -1192,7 +1193,7 @@ namespace {
}
#if _WIN32_WINNT >= 0x0600 // only if Windows Vista or newer
if ((m_open_mode & sparse) == 0)
if (!test(m_open_mode & open_mode_t::sparse))
{
typedef DWORD (WINAPI *GetFileInformationByHandleEx_t)(HANDLE hFile
, FILE_INFO_BY_HANDLE_CLASS FileInformationClass
@ -1247,7 +1248,7 @@ namespace {
// is less than the file size. Otherwise we would just
// update the modification time of the file for no good
// reason.
if ((m_open_mode & sparse) == 0
if (!test(m_open_mode & open_mode_t::sparse)
&& std::int64_t(st.st_blocks) < (s + st.st_blksize - 1) / st.st_blksize)
{
// How do we know that the file is already allocated?

View File

@ -99,7 +99,7 @@ namespace libtorrent {
file_handle file_pool::open_file(storage_index_t st, std::string const& p
, file_index_t const file_index, file_storage const& fs
, std::uint32_t const m, error_code& ec)
, open_mode_t const m, error_code& ec)
{
// potentially used to hold a reference to a file object that's
// about to be destructed. If we have such object we assign it to
@ -119,8 +119,8 @@ namespace libtorrent {
#endif
TORRENT_ASSERT(is_complete(p));
TORRENT_ASSERT((m & file::rw_mask) == file::read_only
|| (m & file::rw_mask) == file::read_write);
TORRENT_ASSERT((m & open_mode_t::rw_mask) == open_mode_t::read_only
|| (m & open_mode_t::rw_mask) == open_mode_t::read_write);
auto const i = m_files.find(std::make_pair(st, file_index));
if (i != m_files.end())
{
@ -130,9 +130,9 @@ namespace libtorrent {
// if we asked for a file in write mode,
// and the cached file is is not opened in
// write mode, re-open it
if ((((e.mode & file::rw_mask) != file::read_write)
&& ((m & file::rw_mask) == file::read_write))
|| (e.mode & file::random_access) != (m & file::random_access))
if ((((e.mode & open_mode_t::rw_mask) != open_mode_t::read_write)
&& ((m & open_mode_t::rw_mask) == open_mode_t::read_write))
|| (e.mode & open_mode_t::random_access) != (m & open_mode_t::random_access))
{
file_handle new_file = std::make_shared<file>();
@ -182,26 +182,23 @@ namespace libtorrent {
namespace {
std::uint32_t to_file_open_mode(std::uint32_t const mode)
std::uint32_t to_file_open_mode(open_mode_t const mode)
{
std::uint32_t ret = 0;
switch (mode & file::rw_mask)
{
case file::read_only:
ret = file_open_mode::read_only;
break;
case file::write_only:
ret = file_open_mode::write_only;
break;
case file::read_write:
ret = file_open_mode::read_write;
break;
}
open_mode_t const rw_mode = mode & open_mode_t::rw_mask;
if (mode & file::sparse) ret |= file_open_mode::sparse;
if (mode & file::no_atime) ret |= file_open_mode::no_atime;
if (mode & file::random_access) ret |= file_open_mode::random_access;
if (mode & file::lock_file) ret |= file_open_mode::locked;
ret = (rw_mode == open_mode_t::read_only)
? file_open_mode::read_only
: (rw_mode == open_mode_t::write_only)
? file_open_mode::write_only
: (rw_mode == open_mode_t::read_write)
? file_open_mode::read_write
: 0;
if (test(mode & open_mode_t::sparse)) ret |= file_open_mode::sparse;
if (test(mode & open_mode_t::no_atime)) ret |= file_open_mode::no_atime;
if (test(mode & open_mode_t::random_access)) ret |= file_open_mode::random_access;
if (test(mode & open_mode_t::lock_file)) ret |= file_open_mode::locked;
return ret;
}

View File

@ -92,7 +92,7 @@ namespace libtorrent {
error_code ec;
std::string fn = combine_path(m_path, m_name);
m_file.open(fn, file::read_only, ec);
m_file.open(fn, open_mode_t::read_only, ec);
if (ec) return;
// parse header
@ -178,7 +178,7 @@ namespace libtorrent {
TORRENT_ASSERT(offset >= 0);
std::unique_lock<std::mutex> l(m_mutex);
open_file(file::read_write, ec);
open_file(open_mode_t::read_write, ec);
if (ec) return -1;
auto const i = m_piece_map.find(piece);
@ -206,7 +206,7 @@ namespace libtorrent {
}
slot_index_t const slot = i->second;
open_file(file::read_write, ec);
open_file(open_mode_t::read_write, ec);
if (ec) return -1;
l.unlock();
@ -215,15 +215,15 @@ namespace libtorrent {
return int(m_file.readv(slot_offset + offset, bufs, ec));
}
void part_file::open_file(std::uint32_t const mode, error_code& ec)
void part_file::open_file(open_mode_t const mode, error_code& ec)
{
if (m_file.is_open()
&& ((m_file.open_mode() & file::rw_mask) == mode
|| mode == file::read_only)) return;
&& ((m_file.open_mode() & open_mode_t::rw_mask) == mode
|| mode == open_mode_t::read_only)) return;
std::string fn = combine_path(m_path, m_name);
m_file.open(fn, mode, ec);
if (((mode & file::rw_mask) != file::read_only)
if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only)
&& ec == boost::system::errc::no_such_file_or_directory)
{
// this means the directory the file is in doesn't exist.
@ -301,7 +301,7 @@ namespace libtorrent {
if (i != m_piece_map.end())
{
slot_index_t const slot = i->second;
open_file(file::read_only, ec);
open_file(open_mode_t::read_only, ec);
if (ec) return;
if (!buf) buf.reset(new char[m_piece_size]);
@ -375,7 +375,7 @@ namespace libtorrent {
return;
}
open_file(file::read_write, ec);
open_file(open_mode_t::read_write, ec);
if (ec) return;
std::vector<char> header(static_cast<std::size_t>(m_header_size));

View File

@ -135,7 +135,7 @@ namespace libtorrent {
if (old_prio == 0 && new_prio != 0)
{
// move stuff out of the part file
file_handle f = open_file(i, file::read_write, ec);
file_handle f = open_file(i, open_mode_t::read_write, ec);
if (ec) return;
need_partfile();
@ -165,7 +165,7 @@ namespace libtorrent {
if (exists(fp))
new_prio = 1;
/*
file_handle f = open_file(i, file::read_only, ec);
file_handle f = open_file(i, open_mode_t::read_only, ec);
if (ec.ec != boost::system::errc::no_such_file_or_directory)
{
if (ec) return;
@ -272,8 +272,8 @@ namespace libtorrent {
}
}
ec.ec.clear();
file_handle f = open_file(file_index, file::read_write
| file::random_access, ec);
file_handle f = open_file(file_index, open_mode_t::read_write
| open_mode_t::random_access, ec);
if (ec)
{
ec.file(file_index);
@ -467,7 +467,7 @@ namespace libtorrent {
int default_storage::readv(span<iovec_t const> bufs
, piece_index_t const piece, int const offset
, std::uint32_t const flags, storage_error& error)
, open_mode_t const flags, storage_error& error)
{
#ifdef TORRENT_SIMULATE_SLOW_READ
std::this_thread::sleep_for(seconds(1));
@ -506,7 +506,7 @@ namespace libtorrent {
}
file_handle handle = open_file(file_index
, file::read_only | flags, ec);
, open_mode_t::read_only | flags, ec);
if (ec) return -1;
error_code e;
@ -534,7 +534,7 @@ namespace libtorrent {
int default_storage::writev(span<iovec_t const> bufs
, piece_index_t const piece, int const offset
, std::uint32_t const flags, storage_error& error)
, open_mode_t const flags, storage_error& error)
{
return readwritev(files(), bufs, piece, offset, error
, [this, flags](file_index_t const file_index
@ -573,7 +573,7 @@ namespace libtorrent {
m_stat_cache.set_dirty(file_index);
file_handle handle = open_file(file_index
, file::read_write, ec);
, open_mode_t::read_write, ec);
if (ec) return -1;
error_code e;
@ -600,10 +600,10 @@ namespace libtorrent {
}
file_handle default_storage::open_file(file_index_t const file
, std::uint32_t mode, storage_error& ec) const
, open_mode_t mode, storage_error& ec) const
{
file_handle h = open_file_impl(file, mode, ec.ec);
if (((mode & file::rw_mask) != file::read_only)
if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only)
&& ec.ec == boost::system::errc::no_such_file_or_directory)
{
// this means the directory the file is in doesn't exist.
@ -631,7 +631,7 @@ namespace libtorrent {
}
TORRENT_ASSERT(h);
if (m_allocate_files && (mode & file::rw_mask) != file::read_only)
if (m_allocate_files && (mode & open_mode_t::rw_mask) != open_mode_t::read_only)
{
std::unique_lock<std::mutex> l(m_file_created_mutex);
if (m_file_created.size() != files().num_files())
@ -662,37 +662,37 @@ namespace libtorrent {
return h;
}
file_handle default_storage::open_file_impl(file_index_t file, std::uint32_t mode
file_handle default_storage::open_file_impl(file_index_t file, open_mode_t mode
, error_code& ec) const
{
bool const lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false;
if (lock_files) mode |= file::lock_file;
if (lock_files) mode |= open_mode_t::lock_file;
if (!m_allocate_files) mode |= file::sparse;
if (!m_allocate_files) mode |= open_mode_t::sparse;
// files with priority 0 should always be sparse
if (m_file_priority.end_index() > file && m_file_priority[file] == 0)
mode |= file::sparse;
mode |= open_mode_t::sparse;
if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= file::no_atime;
if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= open_mode_t::no_atime;
// if we have a cache already, don't store the data twice by leaving it in the OS cache as well
if (m_settings
&& settings().get_int(settings_pack::disk_io_write_mode)
== settings_pack::disable_os_cache)
{
mode |= file::no_cache;
mode |= open_mode_t::no_cache;
}
file_handle ret = m_pool.open_file(storage_index(), m_save_path, file
, files(), mode, ec);
if (ec && (mode & file::lock_file))
if (ec && test(mode & open_mode_t::lock_file))
{
// we failed to open the file and we're trying to lock it. It's
// possible we're failing because we have another handle to this
// file in use (but waiting to be closed). Just retry to open it
// without locking.
mode &= ~file::lock_file;
mode &= ~open_mode_t::lock_file;
ret = m_pool.open_file(storage_index(), m_save_path, file, files()
, mode, ec);
}
@ -740,12 +740,12 @@ namespace {
status_t move_storage(std::string const&, int, storage_error&) override { return status_t::no_error; }
int readv(span<iovec_t const> bufs
, piece_index_t, int, std::uint32_t, storage_error&) override
, piece_index_t, int, open_mode_t, storage_error&) override
{
return bufs_size(bufs);
}
int writev(span<iovec_t const> bufs
, piece_index_t, int, std::uint32_t, storage_error&) override
, piece_index_t, int, open_mode_t, storage_error&) override
{
return bufs_size(bufs);
}
@ -773,7 +773,7 @@ namespace {
void initialize(storage_error&) override {}
int readv(span<iovec_t const> bufs
, piece_index_t, int, std::uint32_t, storage_error&) override
, piece_index_t, int, open_mode_t, storage_error&) override
{
int ret = 0;
for (auto const& b : bufs)
@ -784,7 +784,7 @@ namespace {
return 0;
}
int writev(span<iovec_t const> bufs
, piece_index_t, int, std::uint32_t, storage_error&) override
, piece_index_t, int, open_mode_t, storage_error&) override
{
int ret = 0;
for (auto const& b : bufs)

View File

@ -552,7 +552,7 @@ namespace libtorrent {
{
ec.clear();
file f;
if (!f.open(filename, file::read_only, ec)) return -1;
if (!f.open(filename, open_mode_t::read_only, ec)) return -1;
std::int64_t s = f.get_size(ec);
if (ec) return -1;
v.resize(std::size_t(s));

View File

@ -192,7 +192,7 @@ void generate_files(lt::torrent_info const& ti, std::string const& path
iovec_t b = { &buffer[0], size_t(piece_size) };
storage_error ec;
int ret = st.writev(b, i, 0, 0, ec);
int ret = st.writev(b, i, 0, open_mode_t::read_only, ec);
if (ret != piece_size || ec)
{
std::printf("ERROR writing files: (%d expected %d) %s\n"

View File

@ -658,7 +658,7 @@ void create_random_files(std::string const& path, const int file_sizes[], int nu
full_path = combine_path(full_path, filename);
int to_write = file_sizes[i];
file f(full_path, file::write_only, ec);
file f(full_path, open_mode_t::write_only, ec);
if (ec) std::printf("failed to create file \"%s\": (%d) %s\n"
, full_path.c_str(), ec.value(), ec.message().c_str());
std::int64_t offset = 0;

View File

@ -51,12 +51,12 @@ struct test_storage_impl : storage_interface
void initialize(storage_error& ec) override {}
int readv(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override
{
return bufs_size(bufs);
}
int writev(span<iovec_t const> bufs
, piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override
, piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override
{
return bufs_size(bufs);
}

View File

@ -132,7 +132,7 @@ void test_checking(int flags = read_only_files)
path = combine_path(path, name);
error_code ec;
file f(path, file::read_write, ec);
file f(path, open_mode_t::read_write, ec);
if (ec) std::printf("ERROR: opening file \"%s\": (%d) %s\n"
, path.c_str(), ec.value(), ec.message().c_str());
f.set_size(file_sizes[i] / 2, ec);

View File

@ -52,7 +52,7 @@ int touch_file(std::string const& filename, int size)
file f;
error_code ec;
if (!f.open(filename, file::write_only, ec)) return -1;
if (!f.open(filename, open_mode_t::write_only, ec)) return -1;
if (ec) return -1;
iovec_t b = {&v[0], v.size()};
std::int64_t written = f.writev(0, b, ec);
@ -283,9 +283,9 @@ TORRENT_TEST(file)
error_code ec;
file f;
#if TORRENT_USE_UNC_PATHS || !defined _WIN32
TEST_CHECK(f.open("con", file::read_write, ec));
TEST_CHECK(f.open("con", open_mode_t::read_write, ec));
#else
TEST_CHECK(f.open("test_file", file::read_write, ec));
TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec));
#endif
if (ec)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
@ -316,7 +316,7 @@ TORRENT_TEST(hard_link)
// read that file and assert we get the same stuff we wrote to the first file
error_code ec;
file f;
TEST_CHECK(f.open("original_file", file::read_write, ec));
TEST_CHECK(f.open("original_file", open_mode_t::read_write, ec));
if (ec)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code());
@ -336,7 +336,7 @@ TORRENT_TEST(hard_link)
TEST_EQUAL(ec, error_code());
TEST_CHECK(f.open("second_link", file::read_write, ec));
TEST_CHECK(f.open("second_link", open_mode_t::read_write, ec));
if (ec)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code());
@ -363,7 +363,7 @@ TORRENT_TEST(coalesce_buffer)
{
error_code ec;
file f;
TEST_CHECK(f.open("test_file", file::read_write, ec));
TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec));
if (ec)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code());
@ -371,7 +371,7 @@ TORRENT_TEST(coalesce_buffer)
char test[] = "test";
char foobar[] = "foobar";
iovec_t b[2] = {{test, 4}, {foobar, 6}};
TEST_EQUAL(f.writev(0, b, ec, file::coalesce_buffers), 4 + 6);
TEST_EQUAL(f.writev(0, b, ec, open_mode_t::coalesce_buffers), 4 + 6);
if (ec)
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_CHECK(!ec);

View File

@ -146,7 +146,7 @@ void write_test_file()
std::srand(unsigned(std::time(nullptr)));
std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand);
error_code ec;
file test_file("test_file", file::write_only, ec);
file test_file("test_file", open_mode_t::write_only, ec);
TEST_CHECK(!ec);
if (ec) std::printf("file error: %s\n", ec.message().c_str());
iovec_t b = { data_buffer, 3216};

View File

@ -242,50 +242,50 @@ void run_storage_tests(std::shared_ptr<torrent_info> info
// write piece 1 (in slot 0)
iovec_t iov = { piece1.data(), half};
ret = s->writev(iov, piece_index_t(0), 0, 0, ec);
ret = s->writev(iov, piece_index_t(0), 0, open_mode_t::read_write, ec);
if (ret != half) print_error("writev", ret, ec);
iov = { piece1.data() + half, half };
ret = s->writev(iov, piece_index_t(0), half, 0, ec);
ret = s->writev(iov, piece_index_t(0), half, open_mode_t::read_write, ec);
if (ret != half) print_error("writev", ret, ec);
// test unaligned read (where the bytes are aligned)
iov = { piece + 3, piece_size - 9};
ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, ec);
if (ret != piece_size - 9) print_error("readv",ret, ec);
TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.data()+3));
// test unaligned read (where the bytes are not aligned)
iov = { piece, piece_size - 9};
ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, ec);
TEST_CHECK(ret == piece_size - 9);
if (ret != piece_size - 9) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3));
// verify piece 1
iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(0), 0, 0, ec);
ret = s->readv(iov, piece_index_t(0), 0, open_mode_t::read_write, ec);
TEST_CHECK(ret == piece_size);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data()));
// do the same with piece 0 and 2 (in slot 1 and 2)
iov = { piece0.data(), piece_size };
ret = s->writev(iov, piece_index_t(1), 0, 0, ec);
ret = s->writev(iov, piece_index_t(1), 0, open_mode_t::read_write, ec);
if (ret != piece_size) print_error("writev", ret, ec);
iov = { piece2.data(), piece_size };
ret = s->writev(iov, piece_index_t(2), 0, 0, ec);
ret = s->writev(iov, piece_index_t(2), 0, open_mode_t::read_write, ec);
if (ret != piece_size) print_error("writev", ret, ec);
// verify piece 0 and 2
iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(1), 0, 0, ec);
ret = s->readv(iov, piece_index_t(1), 0, open_mode_t::read_write, ec);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data()));
iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(2), 0, 0, ec);
ret = s->readv(iov, piece_index_t(2), 0, open_mode_t::read_write, ec);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data()));
@ -337,7 +337,7 @@ void test_remove(std::string const& test_path, bool unbuffered)
iovec_t b = {&buf[0], 4};
storage_error se;
s->writev(b, piece_index_t(2), 0, 0, se);
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage"
, combine_path("folder1", "test2.tmp")))));
@ -348,7 +348,7 @@ void test_remove(std::string const& test_path, bool unbuffered)
, combine_path("folder1", "test2.tmp"))), &st, ec);
TEST_EQUAL(st.file_size, 8);
s->writev(b, piece_index_t(4), 0, 0, se);
s->writev(b, piece_index_t(4), 0, open_mode_t::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage"
, combine_path("_folder3", combine_path("subfolder", "test5.tmp"))))));
@ -1362,7 +1362,7 @@ TORRENT_TEST(move_storage_to_self)
iovec_t const b = {&buf[0], 4};
storage_error se;
s->writev(b, piece_index_t(1), 0, 0, se);
s->writev(b, piece_index_t(1), 0, open_mode_t::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("folder2", "test3.tmp"))));
TEST_CHECK(exists(combine_path(test_path, combine_path("_folder3", "test4.tmp"))));
@ -1391,7 +1391,7 @@ TORRENT_TEST(move_storage_into_self)
iovec_t const b = {&buf[0], 4};
storage_error se;
s->writev(b, piece_index_t(2), 0, 0, se);
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se);
std::string const test_path = combine_path(save_path, combine_path("temp_storage", "folder1"));
s->move_storage(test_path, 0, se);
@ -1437,7 +1437,7 @@ TORRENT_TEST(dont_move_intermingled_files)
iovec_t b = {&buf[0], 4};
storage_error se;
s->writev(b, piece_index_t(2), 0, 0, se);
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se);
error_code ec;
create_directory(combine_path(save_path, combine_path("temp_storage"
@ -1445,11 +1445,11 @@ TORRENT_TEST(dont_move_intermingled_files)
TEST_EQUAL(ec, boost::system::errc::success);
file f;
f.open(combine_path(save_path, combine_path("temp_storage", "alien1.tmp"))
, file::write_only, ec);
, open_mode_t::write_only, ec);
f.close();
TEST_EQUAL(ec, boost::system::errc::success);
f.open(combine_path(save_path, combine_path("temp_storage"
, combine_path("folder1", "alien2.tmp"))), file::write_only, ec);
, combine_path("folder1", "alien2.tmp"))), open_mode_t::write_only, ec);
f.close();
TEST_EQUAL(ec, boost::system::errc::success);

View File

@ -89,7 +89,7 @@ struct test_storage : default_storage
span<iovec_t const> bufs
, piece_index_t piece_index
, int offset
, std::uint32_t const flags
, open_mode_t const flags
, storage_error& se) override
{
std::unique_lock<std::mutex> l(m_mutex);

View File

@ -50,7 +50,7 @@ TORRENT_TEST(web_seed_redirect)
char random_data[16000];
std::generate(random_data, random_data + sizeof(random_data), random_byte);
file f("test_file", file::write_only, ec);
file f("test_file", open_mode_t::write_only, ec);
if (ec)
{
std::printf("failed to create file \"test_file\": (%d) %s\n"