]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/impl/file_posix.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / impl / file_posix.ipp
CommitLineData
b32b8144
FG
1//
2// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_CORE_IMPL_FILE_POSIX_IPP
11#define BOOST_BEAST_CORE_IMPL_FILE_POSIX_IPP
12
13#if ! defined(BOOST_BEAST_NO_POSIX_FADVISE)
14# if defined(__APPLE__) || (defined(ANDROID) && (__ANDROID_API__ < 21))
15# define BOOST_BEAST_NO_POSIX_FADVISE
16# endif
17#endif
18
19#if ! defined(BOOST_BEAST_USE_POSIX_FADVISE)
20# if ! defined(BOOST_BEAST_NO_POSIX_FADVISE)
21# define BOOST_BEAST_USE_POSIX_FADVISE 1
22# else
23# define BOOST_BEAST_USE_POSIX_FADVISE 0
24# endif
25#endif
26
27#include <limits>
28#include <fcntl.h>
29#include <sys/types.h>
30#include <sys/uio.h>
31#include <sys/stat.h>
32#include <unistd.h>
33#include <limits.h>
34
35namespace boost {
36namespace beast {
37
38namespace detail {
39
40inline
41int
42file_posix_close(int fd)
43{
44 for(;;)
45 {
46 if(! ::close(fd))
47 break;
48 int const ev = errno;
49 if(errno != EINTR)
50 return ev;
51 }
52 return 0;
53}
54
55} // detail
56
57inline
58file_posix::
59~file_posix()
60{
61 if(fd_ != -1)
62 detail::file_posix_close(fd_);
63}
64
65inline
66file_posix::
67file_posix(file_posix&& other)
68 : fd_(other.fd_)
69{
70 other.fd_ = -1;
71}
72
73inline
74file_posix&
75file_posix::
76operator=(file_posix&& other)
77{
78 if(&other == this)
79 return *this;
80 if(fd_ != -1)
81 detail::file_posix_close(fd_);
82 fd_ = other.fd_;
83 other.fd_ = -1;
84 return *this;
85}
86
87inline
88void
89file_posix::
90native_handle(native_handle_type fd)
91{
92 if(fd_ != -1)
93 detail::file_posix_close(fd_);
94 fd_ = fd;
95}
96
97inline
98void
99file_posix::
100close(error_code& ec)
101{
102 if(fd_ != -1)
103 {
104 auto const ev =
105 detail::file_posix_close(fd_);
106 if(ev)
107 ec.assign(ev, generic_category());
108 else
109 ec.assign(0, ec.category());
110 fd_ = -1;
111 }
112 else
113 {
114 ec.assign(0, ec.category());
115 }
116}
117
118inline
119void
120file_posix::
121open(char const* path, file_mode mode, error_code& ec)
122{
123 if(fd_ != -1)
124 {
125 auto const ev =
126 detail::file_posix_close(fd_);
127 if(ev)
128 ec.assign(ev, generic_category());
129 else
130 ec.assign(0, ec.category());
131 fd_ = -1;
132 }
133 int f = 0;
134#if BOOST_BEAST_USE_POSIX_FADVISE
135 int advise = 0;
136#endif
137 switch(mode)
138 {
139 default:
140 case file_mode::read:
141 f = O_RDONLY;
142 #if BOOST_BEAST_USE_POSIX_FADVISE
143 advise = POSIX_FADV_RANDOM;
144 #endif
145 break;
146 case file_mode::scan:
147 f = O_RDONLY;
148 #if BOOST_BEAST_USE_POSIX_FADVISE
149 advise = POSIX_FADV_SEQUENTIAL;
150 #endif
151 break;
152
153 case file_mode::write:
154 f = O_RDWR | O_CREAT | O_TRUNC;
155 #if BOOST_BEAST_USE_POSIX_FADVISE
156 advise = POSIX_FADV_RANDOM;
157 #endif
158 break;
159
160 case file_mode::write_new:
161 f = O_RDWR | O_CREAT | O_EXCL;
162 #if BOOST_BEAST_USE_POSIX_FADVISE
163 advise = POSIX_FADV_RANDOM;
164 #endif
165 break;
166
167 case file_mode::write_existing:
168 f = O_RDWR | O_EXCL;
169 #if BOOST_BEAST_USE_POSIX_FADVISE
170 advise = POSIX_FADV_RANDOM;
171 #endif
172 break;
173
174 case file_mode::append:
175 f = O_RDWR | O_CREAT | O_TRUNC;
176 #if BOOST_BEAST_USE_POSIX_FADVISE
177 advise = POSIX_FADV_SEQUENTIAL;
178 #endif
179 break;
180
181 case file_mode::append_new:
182 f = O_RDWR | O_CREAT | O_EXCL;
183 #if BOOST_BEAST_USE_POSIX_FADVISE
184 advise = POSIX_FADV_SEQUENTIAL;
185 #endif
186 break;
187
188 case file_mode::append_existing:
189 f = O_RDWR | O_EXCL;
190 #if BOOST_BEAST_USE_POSIX_FADVISE
191 advise = POSIX_FADV_SEQUENTIAL;
192 #endif
193 break;
194 }
195 for(;;)
196 {
197 fd_ = ::open(path, f, 0644);
198 if(fd_ != -1)
199 break;
200 auto const ev = errno;
201 if(ev != EINTR)
202 {
203 ec.assign(ev, generic_category());
204 return;
205 }
206 }
207#if BOOST_BEAST_USE_POSIX_FADVISE
208 if(::posix_fadvise(fd_, 0, 0, advise))
209 {
210 auto const ev = errno;
211 detail::file_posix_close(fd_);
212 fd_ = -1;
213 ec.assign(ev, generic_category());
214 return;
215 }
216#endif
217 ec.assign(0, ec.category());
218}
219
220inline
221std::uint64_t
222file_posix::
223size(error_code& ec) const
224{
225 if(fd_ == -1)
226 {
227 ec.assign(errc::invalid_argument, generic_category());
228 return 0;
229 }
230 struct stat st;
231 if(::fstat(fd_, &st) != 0)
232 {
233 ec.assign(errno, generic_category());
234 return 0;
235 }
236 ec.assign(0, ec.category());
237 return st.st_size;
238}
239
240inline
241std::uint64_t
242file_posix::
243pos(error_code& ec) const
244{
245 if(fd_ == -1)
246 {
247 ec.assign(errc::invalid_argument, generic_category());
248 return 0;
249 }
250 auto const result = ::lseek(fd_, 0, SEEK_CUR);
251 if(result == (off_t)-1)
252 {
253 ec.assign(errno, generic_category());
254 return 0;
255 }
256 ec.assign(0, ec.category());
257 return result;
258}
259
260inline
261void
262file_posix::
263seek(std::uint64_t offset, error_code& ec)
264{
265 if(fd_ == -1)
266 {
267 ec.assign(errc::invalid_argument, generic_category());
268 return;
269 }
270 auto const result = ::lseek(fd_, offset, SEEK_SET);
271 if(result == static_cast<off_t>(-1))
272 {
273 ec.assign(errno, generic_category());
274 return;
275 }
276 ec.assign(0, ec.category());
277}
278
279inline
280std::size_t
281file_posix::
282read(void* buffer, std::size_t n, error_code& ec) const
283{
284 if(fd_ == -1)
285 {
286 ec.assign(errc::invalid_argument, generic_category());
287 return 0;
288 }
289 std::size_t nread = 0;
290 while(n > 0)
291 {
292 auto const amount = static_cast<ssize_t>((std::min)(
293 n, static_cast<std::size_t>(SSIZE_MAX)));
294 auto const result = ::read(fd_, buffer, amount);
295 if(result == -1)
296 {
297 auto const ev = errno;
298 if(ev == EINTR)
299 continue;
300 ec.assign(ev, generic_category());
301 return nread;
302 }
303 if(result == 0)
304 {
305 // short read
306 return nread;
307 }
308 n -= result;
309 nread += result;
310 buffer = reinterpret_cast<char*>(buffer) + result;
311 }
312 return nread;
313}
314
315inline
316std::size_t
317file_posix::
318write(void const* buffer, std::size_t n, error_code& ec)
319{
320 if(fd_ == -1)
321 {
322 ec.assign(errc::invalid_argument, generic_category());
323 return 0;
324 }
325 std::size_t nwritten = 0;
326 while(n > 0)
327 {
328 auto const amount = static_cast<ssize_t>((std::min)(
329 n, static_cast<std::size_t>(SSIZE_MAX)));
330 auto const result = ::write(fd_, buffer, amount);
331 if(result == -1)
332 {
333 auto const ev = errno;
334 if(ev == EINTR)
335 continue;
336 ec.assign(ev, generic_category());
337 return nwritten;
338 }
339 n -= result;
340 nwritten += result;
341 buffer = reinterpret_cast<char const*>(buffer) + result;
342 }
343 return nwritten;
344}
345
346} // beast
347} // boost
348
349#endif