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