diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index c1f70b50c..6e4ab67f2 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -52,6 +52,18 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/size_type.hpp" #include "libtorrent/config.hpp" +#ifdef TORRENT_WINDOWS +// windows part +#include +#include +#else +// posix part +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#endif namespace libtorrent { namespace fs = boost::filesystem; @@ -60,53 +72,28 @@ namespace libtorrent { public: - class seek_mode + enum { - friend class file; - private: - seek_mode(int v): m_val(v) {} - int m_val; +#ifdef TORRENT_WINDOWS + read_only = GENERIC_READ, + write_only = GENERIC_WRITE, + read_write = GENERIC_READ | GENERIC_WRITE, + begin = FILE_BEGIN, + end = FILE_END, +#else + begin = SEEK_SET, + end = SEEK_END, + read_only = O_RDONLY, + write_only = O_WRONLY | O_CREAT, + read_write = O_RDWR | O_CREAT, +#endif }; - static const seek_mode begin; - static const seek_mode end; - - class open_mode - { - friend class file; - public: - - open_mode(): m_mask(0) {} - open_mode operator|(open_mode m) const - { return open_mode(m.m_mask | m_mask); } - - open_mode operator&(open_mode m) const - { return open_mode(m.m_mask & m_mask); } - - open_mode operator|=(open_mode m) - { - m_mask |= m.m_mask; - return *this; - } - - bool operator==(open_mode m) const { return m_mask == m.m_mask; } - bool operator!=(open_mode m) const { return m_mask != m.m_mask; } - operator bool() const { return m_mask != 0; } - - private: - - open_mode(int val): m_mask(val) {} - int m_mask; - }; - - static const open_mode in; - static const open_mode out; - file(); - file(fs::path const& p, open_mode m, error_code& ec); + file(fs::path const& p, int m, error_code& ec); ~file(); - bool open(fs::path const& p, open_mode m, error_code& ec); + bool open(fs::path const& p, int m, error_code& ec); bool is_open() const; void close(); bool set_size(size_type size, error_code& ec); @@ -114,7 +101,7 @@ namespace libtorrent 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, error_code& ec); + size_type seek(size_type pos, int m, error_code& ec); size_type tell(error_code& ec); private: @@ -125,7 +112,7 @@ namespace libtorrent int m_fd; #endif #ifndef NDEBUG - open_mode m_open_mode; + int m_open_mode; #endif }; diff --git a/include/libtorrent/file_pool.hpp b/include/libtorrent/file_pool.hpp index cbabfe807..c25fbfd66 100644 --- a/include/libtorrent/file_pool.hpp +++ b/include/libtorrent/file_pool.hpp @@ -66,7 +66,7 @@ namespace libtorrent file_pool(int size = 40): m_size(size) {} boost::shared_ptr open_file(void* st, fs::path const& p - , file::open_mode m, error_code& ec); + , int m, error_code& ec); void release(void* st); void release(fs::path const& p); void resize(int size); @@ -81,7 +81,7 @@ namespace libtorrent fs::path file_path; void* key; ptime last_use; - file::open_mode mode; + int mode; }; typedef multi_index_container< diff --git a/src/file.cpp b/src/file.cpp index bd3a0d368..0ca89ca73 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -67,14 +67,6 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8); #include #include -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#ifndef O_RANDOM -#define O_RANDOM 0 -#endif - #ifdef UNICODE #include "libtorrent/storage.hpp" #endif @@ -104,18 +96,6 @@ namespace return s; } } -#else - - enum { mode_in = 1, mode_out = 2 }; - - mode_t map_open_mode(int m) - { - if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM; - if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM; - if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM; - TORRENT_ASSERT(false); - return 0; - } #endif } @@ -124,18 +104,6 @@ namespace libtorrent { namespace fs = boost::filesystem; -#ifdef TORRENT_WINDOWS - const file::open_mode file::in(GENERIC_READ); - const file::open_mode file::out(GENERIC_WRITE); - const file::seek_mode file::begin(FILE_BEGIN); - const file::seek_mode file::end(FILE_END); -#else - const file::open_mode file::in(mode_in); - const file::open_mode file::out(mode_out); - const file::seek_mode file::begin(SEEK_SET); - const file::seek_mode file::end(SEEK_END); -#endif - file::file() #ifdef TORRENT_WINDOWS : m_file_handle(INVALID_HANDLE_VALUE) @@ -147,7 +115,7 @@ namespace libtorrent #endif {} - file::file(fs::path const& path, open_mode mode, error_code& ec) + file::file(fs::path const& path, int mode, error_code& ec) #ifdef TORRENT_WINDOWS : m_file_handle(INVALID_HANDLE_VALUE) #else @@ -165,7 +133,7 @@ namespace libtorrent close(); } - bool file::open(fs::path const& path, open_mode mode, error_code& ec) + bool file::open(fs::path const& path, int mode, error_code& ec) { close(); #ifdef TORRENT_WINDOWS @@ -178,10 +146,10 @@ namespace libtorrent m_file_handle = CreateFile( file_path.c_str() - , mode.m_mask + , mode , FILE_SHARE_READ , 0 - , (mode & out)?OPEN_ALWAYS:OPEN_EXISTING + , (mode == read_write || mode == write_only)?OPEN_ALWAYS:OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , 0); @@ -192,7 +160,7 @@ namespace libtorrent } // try to make the file sparse if supported - if (mode & out) + if (mode == write_only || mode == read_write) { DWORD temp; ::DeviceIoControl(m_file_handle, FSCTL_SET_SPARSE, 0, 0 @@ -205,8 +173,8 @@ namespace libtorrent | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - m_fd = ::open(path.native_file_string().c_str() - , map_open_mode(mode.m_mask), permissions); + m_fd = ::open(path.native_file_string().c_str() + , mode, permissions); if (m_fd == -1) { @@ -248,7 +216,7 @@ namespace libtorrent size_type file::read(char* buf, size_type num_bytes, error_code& ec) { - TORRENT_ASSERT((m_open_mode & in) == in); + TORRENT_ASSERT(m_open_mode == read_only || m_open_mode == read_write); TORRENT_ASSERT(buf); TORRENT_ASSERT(num_bytes >= 0); TORRENT_ASSERT(is_open()); @@ -274,7 +242,7 @@ namespace libtorrent size_type file::write(const char* buf, size_type num_bytes, error_code& ec) { - TORRENT_ASSERT((m_open_mode & out) == out); + TORRENT_ASSERT(m_open_mode == write_only || m_open_mode == read_write); TORRENT_ASSERT(buf); TORRENT_ASSERT(num_bytes >= 0); TORRENT_ASSERT(is_open()); @@ -322,21 +290,21 @@ namespace libtorrent return true; } - size_type file::seek(size_type offset, seek_mode m, error_code& ec) + size_type file::seek(size_type offset, int m, error_code& ec) { TORRENT_ASSERT(is_open()); #ifdef TORRENT_WINDOWS LARGE_INTEGER offs; offs.QuadPart = offset; - if (SetFilePointerEx(m_file_handle, offs, &offs, m.m_val) == FALSE) + if (SetFilePointerEx(m_file_handle, offs, &offs, m) == FALSE) { ec = error_code(GetLastError(), get_system_category()); return -1; } return offs.QuadPart; #else - size_type ret = lseek(m_fd, offset, m.m_val); + size_type ret = lseek(m_fd, offset, m); if (ret < 0) ec = error_code(errno, get_posix_category()); return ret; #endif diff --git a/src/file_pool.cpp b/src/file_pool.cpp index 865c071ff..92d8ca5cb 100644 --- a/src/file_pool.cpp +++ b/src/file_pool.cpp @@ -43,11 +43,11 @@ namespace libtorrent using boost::multi_index::get; boost::shared_ptr file_pool::open_file(void* st, fs::path const& p - , file::open_mode m, error_code& ec) + , int m, error_code& ec) { TORRENT_ASSERT(st != 0); TORRENT_ASSERT(p.is_complete()); - TORRENT_ASSERT(m == file::in || m == (file::in | file::out)); + TORRENT_ASSERT(m == file::read_only || m == file::read_write); boost::mutex::scoped_lock l(m_mutex); typedef nth_index::type path_view; path_view& pt = get<0>(m_files); @@ -68,7 +68,11 @@ namespace libtorrent } e.key = st; - if ((e.mode & m) != m) + // 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::read_write) + && (m == file::read_write)) { // close the file before we open it with // the new read/write privilages diff --git a/src/storage.cpp b/src/storage.cpp index 28464edf2..370c6348d 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -530,7 +530,7 @@ namespace libtorrent || m_file_priority[file_index] > 0)) { boost::shared_ptr f = m_pool.open_file(this - , m_save_path / file_iter->path, file::in | file::out, ec); + , m_save_path / file_iter->path, file::read_write, ec); if (ec) { set_error(m_save_path / file_iter->path, ec); @@ -550,7 +550,7 @@ namespace libtorrent { error_code ec; boost::shared_ptr f = m_pool.open_file(this - , m_save_path / file_iter->path, file::in | file::out, ec); + , m_save_path / file_iter->path, file::read_write, ec); if (ec) set_error(m_save_path / file_iter->path, ec); else if (f) { @@ -1083,7 +1083,7 @@ namespace libtorrent fs::path path = m_save_path / file_iter->path; error_code ec; - in = m_pool.open_file(this, path, file::in, ec); + in = m_pool.open_file(this, path, file::read_only, ec); if (!in || ec) { set_error(path, ec); @@ -1200,7 +1200,7 @@ namespace libtorrent fs::path path = m_save_path / file_iter->path; error_code ec; - out = m_pool.open_file(this, path, file::in | file::out, ec); + out = m_pool.open_file(this, path, file::read_write, ec); if (!out || ec) { set_error(path, ec); diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 321e75aca..67f772958 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -222,7 +222,7 @@ namespace libtorrent { file f; error_code ec; - if (!f.open(filename, file::in, ec)) return -1; + if (!f.open(filename, file::read_only, ec)) return -1; f.seek(0, file::end, ec); if (ec) return -1; size_type s = f.tell(ec);