1 /* 2 3 Copyright (c) 2003-2018, Arvid Norberg 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 10 * Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 * Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in 14 the documentation and/or other materials provided with the distribution. 15 * Neither the name of the author nor the names of its 16 contributors may be used to endorse or promote products derived 17 from this software without specific prior written permission. 18 19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 POSSIBILITY OF SUCH DAMAGE. 30 31 */ 32 33 #ifndef TORRENT_FILE_HPP_INCLUDED 34 #define TORRENT_FILE_HPP_INCLUDED 35 36 #include <memory> 37 #include <string> 38 #include <functional> 39 40 #include "libtorrent/config.hpp" 41 #include "libtorrent/string_view.hpp" 42 #include "libtorrent/span.hpp" 43 #include "libtorrent/aux_/storage_utils.hpp" 44 #include "libtorrent/flags.hpp" 45 46 #include "libtorrent/aux_/disable_warnings_push.hpp" 47 48 #include <boost/noncopyable.hpp> 49 50 #ifdef TORRENT_WINDOWS 51 // windows part 52 #include "libtorrent/aux_/windows.hpp" 53 #include <winioctl.h> 54 #include <sys/types.h> 55 #else 56 // posix part 57 #define _FILE_OFFSET_BITS 64 58 59 #ifndef _GNU_SOURCE 60 #define _GNU_SOURCE 61 #endif 62 63 #ifndef _XOPEN_SOURCE 64 #define _XOPEN_SOURCE 600 65 #endif 66 67 #include <unistd.h> 68 #include <sys/uio.h> 69 #include <fcntl.h> 70 #include <sys/types.h> 71 #include <dirent.h> // for DIR 72 73 #undef _FILE_OFFSET_BITS 74 75 #endif 76 77 #include "libtorrent/aux_/disable_warnings_pop.hpp" 78 79 #include "libtorrent/error_code.hpp" 80 #include "libtorrent/assert.hpp" 81 #include "libtorrent/time.hpp" 82 83 namespace libtorrent { 84 85 #ifdef TORRENT_WINDOWS 86 using handle_type = HANDLE; 87 #else 88 using handle_type = int; 89 #endif 90 91 class TORRENT_EXTRA_EXPORT directory : public boost::noncopyable 92 { 93 public: 94 directory(std::string const& path, error_code& ec); 95 ~directory(); 96 void next(error_code& ec); 97 std::string file() const; done() const98 bool done() const { return m_done; } 99 private: 100 #ifdef TORRENT_WINDOWS 101 HANDLE m_handle; 102 WIN32_FIND_DATAW m_fd; 103 #else 104 DIR* m_handle; 105 std::string m_name; 106 #endif 107 bool m_done; 108 }; 109 110 struct file; 111 112 using file_handle = std::shared_ptr<file>; 113 114 // hidden 115 using open_mode_t = flags::bitfield_flag<std::uint32_t, struct open_mode_tag>; 116 117 // the open mode for files. Used for the file constructor or 118 // file::open(). 119 namespace open_mode { 120 121 // open the file for reading only 122 constexpr open_mode_t read_only{}; 123 124 // open the file for writing only 125 constexpr open_mode_t write_only = 0_bit; 126 127 // open the file for reading and writing 128 constexpr open_mode_t read_write = 1_bit; 129 130 // the mask for the bits making up the read-write mode. 131 constexpr open_mode_t rw_mask = read_only | write_only | read_write; 132 133 // open the file in sparse mode (if supported by the 134 // filesystem). 135 constexpr open_mode_t sparse = 2_bit; 136 137 // don't update the access timestamps on the file (if 138 // supported by the operating system and filesystem). 139 // this generally improves disk performance. 140 constexpr open_mode_t no_atime = 3_bit; 141 142 // open the file for random access. This disables read-ahead 143 // logic 144 constexpr open_mode_t random_access = 4_bit; 145 146 // don't put any pressure on the OS disk cache 147 // because of access to this file. We expect our 148 // files to be fairly large, and there is already 149 // a cache at the bittorrent block level. This 150 // may improve overall system performance by 151 // leaving running applications in the page cache 152 constexpr open_mode_t no_cache = 5_bit; 153 154 // this is only used for readv/writev flags 155 constexpr open_mode_t coalesce_buffers = 6_bit; 156 157 // when creating a file, set the hidden attribute (windows only) 158 constexpr open_mode_t attribute_hidden = 7_bit; 159 160 // when creating a file, set the executable attribute 161 constexpr open_mode_t attribute_executable = 8_bit; 162 163 // the mask of all attribute bits 164 constexpr open_mode_t attribute_mask = attribute_hidden | attribute_executable; 165 } 166 167 struct TORRENT_EXTRA_EXPORT file : boost::noncopyable 168 { 169 file(); 170 file(file&&) noexcept; 171 file& operator=(file&&); 172 file(std::string const& p, open_mode_t m, error_code& ec); 173 ~file(); 174 175 bool open(std::string const& p, open_mode_t m, error_code& ec); 176 bool is_open() const; 177 void close(); 178 bool set_size(std::int64_t size, error_code& ec); 179 open_modelibtorrent::file180 open_mode_t open_mode() const { return m_open_mode; } 181 182 std::int64_t writev(std::int64_t file_offset, span<iovec_t const> bufs 183 , error_code& ec, open_mode_t flags = open_mode_t{}); 184 std::int64_t readv(std::int64_t file_offset, span<iovec_t const> bufs 185 , error_code& ec, open_mode_t flags = open_mode_t{}); 186 187 std::int64_t get_size(error_code& ec) const; 188 native_handlelibtorrent::file189 handle_type native_handle() const { return m_file_handle; } 190 191 private: 192 193 handle_type m_file_handle; 194 195 open_mode_t m_open_mode{}; 196 }; 197 } 198 199 #endif // TORRENT_FILE_HPP_INCLUDED 200