2 // Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_CORE_IMPL_FILE_POSIX_IPP
11 #define BOOST_BEAST_CORE_IMPL_FILE_POSIX_IPP
13 #if ! defined(BOOST_BEAST_NO_POSIX_FADVISE)
14 # if defined(__APPLE__) || (defined(ANDROID) && (__ANDROID_API__ < 21))
15 # define BOOST_BEAST_NO_POSIX_FADVISE
19 #if ! defined(BOOST_BEAST_USE_POSIX_FADVISE)
20 # if ! defined(BOOST_BEAST_NO_POSIX_FADVISE)
21 # define BOOST_BEAST_USE_POSIX_FADVISE 1
23 # define BOOST_BEAST_USE_POSIX_FADVISE 0
29 #include <sys/types.h>
42 file_posix_close(int fd)
62 detail::file_posix_close(fd_);
67 file_posix(file_posix&& other)
76 operator=(file_posix&& other)
81 detail::file_posix_close(fd_);
90 native_handle(native_handle_type fd)
93 detail::file_posix_close(fd_);
100 close(error_code& ec)
105 detail::file_posix_close(fd_);
107 ec.assign(ev, generic_category());
109 ec.assign(0, ec.category());
114 ec.assign(0, ec.category());
121 open(char const* path, file_mode mode, error_code& ec)
126 detail::file_posix_close(fd_);
128 ec.assign(ev, generic_category());
130 ec.assign(0, ec.category());
134 #if BOOST_BEAST_USE_POSIX_FADVISE
140 case file_mode::read:
142 #if BOOST_BEAST_USE_POSIX_FADVISE
143 advise = POSIX_FADV_RANDOM;
146 case file_mode::scan:
148 #if BOOST_BEAST_USE_POSIX_FADVISE
149 advise = POSIX_FADV_SEQUENTIAL;
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;
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;
167 case file_mode::write_existing:
169 #if BOOST_BEAST_USE_POSIX_FADVISE
170 advise = POSIX_FADV_RANDOM;
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;
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;
188 case file_mode::append_existing:
190 #if BOOST_BEAST_USE_POSIX_FADVISE
191 advise = POSIX_FADV_SEQUENTIAL;
197 fd_ = ::open(path, f, 0644);
200 auto const ev = errno;
203 ec.assign(ev, generic_category());
207 #if BOOST_BEAST_USE_POSIX_FADVISE
208 if(::posix_fadvise(fd_, 0, 0, advise))
210 auto const ev = errno;
211 detail::file_posix_close(fd_);
213 ec.assign(ev, generic_category());
217 ec.assign(0, ec.category());
223 size(error_code& ec) const
227 ec.assign(errc::invalid_argument, generic_category());
231 if(::fstat(fd_, &st) != 0)
233 ec.assign(errno, generic_category());
236 ec.assign(0, ec.category());
243 pos(error_code& ec) const
247 ec.assign(errc::invalid_argument, generic_category());
250 auto const result = ::lseek(fd_, 0, SEEK_CUR);
251 if(result == (off_t)-1)
253 ec.assign(errno, generic_category());
256 ec.assign(0, ec.category());
263 seek(std::uint64_t offset, error_code& ec)
267 ec.assign(errc::invalid_argument, generic_category());
270 auto const result = ::lseek(fd_, offset, SEEK_SET);
271 if(result == static_cast<off_t>(-1))
273 ec.assign(errno, generic_category());
276 ec.assign(0, ec.category());
282 read(void* buffer, std::size_t n, error_code& ec) const
286 ec.assign(errc::invalid_argument, generic_category());
289 std::size_t nread = 0;
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);
297 auto const ev = errno;
300 ec.assign(ev, generic_category());
310 buffer = reinterpret_cast<char*>(buffer) + result;
318 write(void const* buffer, std::size_t n, error_code& ec)
322 ec.assign(errc::invalid_argument, generic_category());
325 std::size_t nwritten = 0;
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);
333 auto const ev = errno;
336 ec.assign(ev, generic_category());
341 buffer = reinterpret_cast<char const*>(buffer) + result;