83.44% Lines (126/151)
100.00% Functions (12/12)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | // | 1 | // | |||||
| 2 | // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) | 2 | // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) | |||||
| 3 | // | 3 | // | |||||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 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) | 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| 6 | // | 6 | // | |||||
| 7 | // Official repository: https://github.com/cppalliance/http | 7 | // Official repository: https://github.com/cppalliance/http | |||||
| 8 | // | 8 | // | |||||
| 9 | 9 | |||||||
| 10 | #include <boost/http/detail/file_posix.hpp> | 10 | #include <boost/http/detail/file_posix.hpp> | |||||
| 11 | 11 | |||||||
| 12 | #if BOOST_HTTP_USE_POSIX_FILE | 12 | #if BOOST_HTTP_USE_POSIX_FILE | |||||
| 13 | 13 | |||||||
| 14 | #include <boost/core/exchange.hpp> | 14 | #include <boost/core/exchange.hpp> | |||||
| 15 | #include <limits> | 15 | #include <limits> | |||||
| 16 | #include <fcntl.h> | 16 | #include <fcntl.h> | |||||
| 17 | #include <sys/types.h> | 17 | #include <sys/types.h> | |||||
| 18 | #include <sys/uio.h> | 18 | #include <sys/uio.h> | |||||
| 19 | #include <sys/stat.h> | 19 | #include <sys/stat.h> | |||||
| 20 | #include <unistd.h> | 20 | #include <unistd.h> | |||||
| 21 | #include <limits.h> | 21 | #include <limits.h> | |||||
| 22 | 22 | |||||||
| 23 | #if ! defined(BOOST_HTTP_NO_POSIX_FADVISE) | 23 | #if ! defined(BOOST_HTTP_NO_POSIX_FADVISE) | |||||
| 24 | # if defined(__APPLE__) || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) | 24 | # if defined(__APPLE__) || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) | |||||
| 25 | # define BOOST_HTTP_NO_POSIX_FADVISE | 25 | # define BOOST_HTTP_NO_POSIX_FADVISE | |||||
| 26 | # endif | 26 | # endif | |||||
| 27 | #endif | 27 | #endif | |||||
| 28 | 28 | |||||||
| 29 | #if ! defined(BOOST_HTTP_USE_POSIX_FADVISE) | 29 | #if ! defined(BOOST_HTTP_USE_POSIX_FADVISE) | |||||
| 30 | # if ! defined(BOOST_HTTP_NO_POSIX_FADVISE) | 30 | # if ! defined(BOOST_HTTP_NO_POSIX_FADVISE) | |||||
| 31 | # define BOOST_HTTP_USE_POSIX_FADVISE 1 | 31 | # define BOOST_HTTP_USE_POSIX_FADVISE 1 | |||||
| 32 | # else | 32 | # else | |||||
| 33 | # define BOOST_HTTP_USE_POSIX_FADVISE 0 | 33 | # define BOOST_HTTP_USE_POSIX_FADVISE 0 | |||||
| 34 | # endif | 34 | # endif | |||||
| 35 | #endif | 35 | #endif | |||||
| 36 | 36 | |||||||
| 37 | namespace boost { | 37 | namespace boost { | |||||
| 38 | namespace http { | 38 | namespace http { | |||||
| 39 | namespace detail { | 39 | namespace detail { | |||||
| 40 | 40 | |||||||
| 41 | int | 41 | int | |||||
| HITCBC | 42 | 106 | file_posix:: | 42 | 106 | file_posix:: | ||
| 43 | native_close(native_handle_type& fd) | 43 | native_close(native_handle_type& fd) | |||||
| 44 | { | 44 | { | |||||
| 45 | /* https://github.com/boostorg/beast/issues/1445 | 45 | /* https://github.com/boostorg/beast/issues/1445 | |||||
| 46 | 46 | |||||||
| 47 | This function is tuned for Linux / Mac OS: | 47 | This function is tuned for Linux / Mac OS: | |||||
| 48 | 48 | |||||||
| 49 | * only calls close() once | 49 | * only calls close() once | |||||
| 50 | * returns the error directly to the caller | 50 | * returns the error directly to the caller | |||||
| 51 | * does not loop on EINTR | 51 | * does not loop on EINTR | |||||
| 52 | 52 | |||||||
| 53 | If this is incorrect for the platform, then the | 53 | If this is incorrect for the platform, then the | |||||
| 54 | caller will need to implement their own type | 54 | caller will need to implement their own type | |||||
| 55 | meeting the File requirements and use the correct | 55 | meeting the File requirements and use the correct | |||||
| 56 | behavior. | 56 | behavior. | |||||
| 57 | 57 | |||||||
| 58 | See: | 58 | See: | |||||
| 59 | http://man7.org/linux/man-pages/man2/close.2.html | 59 | http://man7.org/linux/man-pages/man2/close.2.html | |||||
| 60 | */ | 60 | */ | |||||
| HITCBC | 61 | 106 | int ev = 0; | 61 | 106 | int ev = 0; | ||
| HITCBC | 62 | 106 | if(fd != -1) | 62 | 106 | if(fd != -1) | ||
| 63 | { | 63 | { | |||||
| HITCBC | 64 | 36 | if(::close(fd) != 0) | 64 | 36 | if(::close(fd) != 0) | ||
| MISUBC | 65 | ✗ | ev = errno; | 65 | ✗ | ev = errno; | ||
| HITCBC | 66 | 36 | fd = -1; | 66 | 36 | fd = -1; | ||
| 67 | } | 67 | } | |||||
| HITCBC | 68 | 106 | return ev; | 68 | 106 | return ev; | ||
| 69 | } | 69 | } | |||||
| 70 | 70 | |||||||
| HITCBC | 71 | 48 | file_posix:: | 71 | 48 | file_posix:: | ||
| 72 | ~file_posix() | 72 | ~file_posix() | |||||
| 73 | { | 73 | { | |||||
| HITCBC | 74 | 48 | native_close(fd_); | 74 | 48 | native_close(fd_); | ||
| HITCBC | 75 | 48 | } | 75 | 48 | } | ||
| 76 | 76 | |||||||
| HITCBC | 77 | 2 | file_posix:: | 77 | 2 | file_posix:: | ||
| 78 | file_posix( | 78 | file_posix( | |||||
| HITCBC | 79 | 2 | file_posix&& other) noexcept | 79 | 2 | file_posix&& other) noexcept | ||
| HITCBC | 80 | 2 | : fd_(boost::exchange(other.fd_, -1)) | 80 | 2 | : fd_(boost::exchange(other.fd_, -1)) | ||
| 81 | { | 81 | { | |||||
| HITCBC | 82 | 2 | } | 82 | 2 | } | ||
| 83 | 83 | |||||||
| 84 | file_posix& | 84 | file_posix& | |||||
| HITCBC | 85 | 6 | file_posix:: | 85 | 6 | file_posix:: | ||
| 86 | operator=( | 86 | operator=( | |||||
| 87 | file_posix&& other) noexcept | 87 | file_posix&& other) noexcept | |||||
| 88 | { | 88 | { | |||||
| HITCBC | 89 | 6 | if(&other == this) | 89 | 6 | if(&other == this) | ||
| HITCBC | 90 | 2 | return *this; | 90 | 2 | return *this; | ||
| HITCBC | 91 | 4 | native_close(fd_); | 91 | 4 | native_close(fd_); | ||
| HITCBC | 92 | 4 | fd_ = other.fd_; | 92 | 4 | fd_ = other.fd_; | ||
| HITCBC | 93 | 4 | other.fd_ = -1; | 93 | 4 | other.fd_ = -1; | ||
| HITCBC | 94 | 4 | return *this; | 94 | 4 | return *this; | ||
| 95 | } | 95 | } | |||||
| 96 | 96 | |||||||
| 97 | void | 97 | void | |||||
| HITCBC | 98 | 2 | file_posix:: | 98 | 2 | file_posix:: | ||
| 99 | native_handle(native_handle_type fd) | 99 | native_handle(native_handle_type fd) | |||||
| 100 | { | 100 | { | |||||
| HITCBC | 101 | 2 | native_close(fd_); | 101 | 2 | native_close(fd_); | ||
| HITCBC | 102 | 2 | fd_ = fd; | 102 | 2 | fd_ = fd; | ||
| HITCBC | 103 | 2 | } | 103 | 2 | } | ||
| 104 | 104 | |||||||
| 105 | void | 105 | void | |||||
| HITCBC | 106 | 8 | file_posix:: | 106 | 8 | file_posix:: | ||
| 107 | close( | 107 | close( | |||||
| 108 | system::error_code& ec) | 108 | system::error_code& ec) | |||||
| 109 | { | 109 | { | |||||
| HITCBC | 110 | 8 | auto const ev = native_close(fd_); | 110 | 8 | auto const ev = native_close(fd_); | ||
| HITCBC | 111 | 8 | if(ev) | 111 | 8 | if(ev) | ||
| MISUBC | 112 | ✗ | ec.assign(ev, | 112 | ✗ | ec.assign(ev, | ||
| 113 | system::system_category()); | 113 | system::system_category()); | |||||
| 114 | else | 114 | else | |||||
| HITCBC | 115 | 8 | ec = {}; | 115 | 8 | ec = {}; | ||
| HITCBC | 116 | 8 | } | 116 | 8 | } | ||
| 117 | 117 | |||||||
| 118 | void | 118 | void | |||||
| HITCBC | 119 | 44 | file_posix:: | 119 | 44 | file_posix:: | ||
| 120 | open(char const* path, file_mode mode, system::error_code& ec) | 120 | open(char const* path, file_mode mode, system::error_code& ec) | |||||
| 121 | { | 121 | { | |||||
| HITCBC | 122 | 44 | auto const ev = native_close(fd_); | 122 | 44 | auto const ev = native_close(fd_); | ||
| HITCBC | 123 | 44 | if(ev) | 123 | 44 | if(ev) | ||
| MISUBC | 124 | ✗ | ec.assign(ev, | 124 | ✗ | ec.assign(ev, | ||
| 125 | system::system_category()); | 125 | system::system_category()); | |||||
| 126 | else | 126 | else | |||||
| HITCBC | 127 | 44 | ec = {}; | 127 | 44 | ec = {}; | ||
| 128 | 128 | |||||||
| HITCBC | 129 | 44 | int f = 0; | 129 | 44 | int f = 0; | ||
| 130 | #if BOOST_HTTP_USE_POSIX_FADVISE | 130 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 131 | 44 | int advise = 0; | 131 | 44 | int advise = 0; | ||
| 132 | #endif | 132 | #endif | |||||
| HITCBC | 133 | 44 | switch(mode) | 133 | 44 | switch(mode) | ||
| 134 | { | 134 | { | |||||
| HITCBC | 135 | 4 | default: | 135 | 4 | default: | ||
| 136 | case file_mode::read: | 136 | case file_mode::read: | |||||
| HITCBC | 137 | 4 | f = O_RDONLY; | 137 | 4 | f = O_RDONLY; | ||
| 138 | #if BOOST_HTTP_USE_POSIX_FADVISE | 138 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 139 | 4 | advise = POSIX_FADV_RANDOM; | 139 | 4 | advise = POSIX_FADV_RANDOM; | ||
| 140 | #endif | 140 | #endif | |||||
| HITCBC | 141 | 4 | break; | 141 | 4 | break; | ||
| HITCBC | 142 | 4 | case file_mode::scan: | 142 | 4 | case file_mode::scan: | ||
| HITCBC | 143 | 4 | f = O_RDONLY; | 143 | 4 | f = O_RDONLY; | ||
| 144 | #if BOOST_HTTP_USE_POSIX_FADVISE | 144 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 145 | 4 | advise = POSIX_FADV_SEQUENTIAL; | 145 | 4 | advise = POSIX_FADV_SEQUENTIAL; | ||
| 146 | #endif | 146 | #endif | |||||
| HITCBC | 147 | 4 | break; | 147 | 4 | break; | ||
| 148 | 148 | |||||||
| HITCBC | 149 | 20 | case file_mode::write: | 149 | 20 | case file_mode::write: | ||
| HITCBC | 150 | 20 | f = O_RDWR | O_CREAT | O_TRUNC; | 150 | 20 | f = O_RDWR | O_CREAT | O_TRUNC; | ||
| 151 | #if BOOST_HTTP_USE_POSIX_FADVISE | 151 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 152 | 20 | advise = POSIX_FADV_RANDOM; | 152 | 20 | advise = POSIX_FADV_RANDOM; | ||
| 153 | #endif | 153 | #endif | |||||
| HITCBC | 154 | 20 | break; | 154 | 20 | break; | ||
| 155 | 155 | |||||||
| HITCBC | 156 | 4 | case file_mode::write_new: | 156 | 4 | case file_mode::write_new: | ||
| HITCBC | 157 | 4 | f = O_RDWR | O_CREAT | O_EXCL; | 157 | 4 | f = O_RDWR | O_CREAT | O_EXCL; | ||
| 158 | #if BOOST_HTTP_USE_POSIX_FADVISE | 158 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 159 | 4 | advise = POSIX_FADV_RANDOM; | 159 | 4 | advise = POSIX_FADV_RANDOM; | ||
| 160 | #endif | 160 | #endif | |||||
| HITCBC | 161 | 4 | break; | 161 | 4 | break; | ||
| 162 | 162 | |||||||
| HITCBC | 163 | 4 | case file_mode::write_existing: | 163 | 4 | case file_mode::write_existing: | ||
| HITCBC | 164 | 4 | f = O_RDWR | O_EXCL; | 164 | 4 | f = O_RDWR | O_EXCL; | ||
| 165 | #if BOOST_HTTP_USE_POSIX_FADVISE | 165 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 166 | 4 | advise = POSIX_FADV_RANDOM; | 166 | 4 | advise = POSIX_FADV_RANDOM; | ||
| 167 | #endif | 167 | #endif | |||||
| HITCBC | 168 | 4 | break; | 168 | 4 | break; | ||
| 169 | 169 | |||||||
| HITCBC | 170 | 4 | case file_mode::append: | 170 | 4 | case file_mode::append: | ||
| HITCBC | 171 | 4 | f = O_WRONLY | O_CREAT | O_APPEND; | 171 | 4 | f = O_WRONLY | O_CREAT | O_APPEND; | ||
| 172 | #if BOOST_HTTP_USE_POSIX_FADVISE | 172 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 173 | 4 | advise = POSIX_FADV_SEQUENTIAL; | 173 | 4 | advise = POSIX_FADV_SEQUENTIAL; | ||
| 174 | #endif | 174 | #endif | |||||
| HITCBC | 175 | 4 | break; | 175 | 4 | break; | ||
| 176 | 176 | |||||||
| HITCBC | 177 | 4 | case file_mode::append_existing: | 177 | 4 | case file_mode::append_existing: | ||
| HITCBC | 178 | 4 | f = O_WRONLY | O_APPEND; | 178 | 4 | f = O_WRONLY | O_APPEND; | ||
| 179 | #if BOOST_HTTP_USE_POSIX_FADVISE | 179 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 180 | 4 | advise = POSIX_FADV_SEQUENTIAL; | 180 | 4 | advise = POSIX_FADV_SEQUENTIAL; | ||
| 181 | #endif | 181 | #endif | |||||
| HITCBC | 182 | 4 | break; | 182 | 4 | break; | ||
| 183 | } | 183 | } | |||||
| 184 | for(;;) | 184 | for(;;) | |||||
| 185 | { | 185 | { | |||||
| HITCBC | 186 | 44 | fd_ = ::open(path, f, 0644); | 186 | 44 | fd_ = ::open(path, f, 0644); | ||
| HITCBC | 187 | 44 | if(fd_ != -1) | 187 | 44 | if(fd_ != -1) | ||
| HITCBC | 188 | 36 | break; | 188 | 36 | break; | ||
| HITCBC | 189 | 8 | auto const ev = errno; | 189 | 8 | auto const ev = errno; | ||
| HITCBC | 190 | 8 | if(ev != EINTR) | 190 | 8 | if(ev != EINTR) | ||
| 191 | { | 191 | { | |||||
| HITCBC | 192 | 8 | ec.assign(ev, | 192 | 8 | ec.assign(ev, | ||
| 193 | system::system_category()); | 193 | system::system_category()); | |||||
| HITCBC | 194 | 8 | return; | 194 | 8 | return; | ||
| 195 | } | 195 | } | |||||
| MISUBC | 196 | ✗ | } | 196 | ✗ | } | ||
| 197 | #if BOOST_HTTP_USE_POSIX_FADVISE | 197 | #if BOOST_HTTP_USE_POSIX_FADVISE | |||||
| HITCBC | 198 | 36 | if(::posix_fadvise(fd_, 0, 0, advise)) | 198 | 36 | if(::posix_fadvise(fd_, 0, 0, advise)) | ||
| 199 | { | 199 | { | |||||
| MISUBC | 200 | ✗ | auto const ev = errno; | 200 | ✗ | auto const ev = errno; | ||
| MISUBC | 201 | ✗ | native_close(fd_); | 201 | ✗ | native_close(fd_); | ||
| MISUBC | 202 | ✗ | ec.assign(ev, | 202 | ✗ | ec.assign(ev, | ||
| 203 | system::system_category()); | 203 | system::system_category()); | |||||
| MISUBC | 204 | ✗ | return; | 204 | ✗ | return; | ||
| 205 | } | 205 | } | |||||
| 206 | #endif | 206 | #endif | |||||
| HITCBC | 207 | 36 | ec = {}; | 207 | 36 | ec = {}; | ||
| 208 | } | 208 | } | |||||
| 209 | 209 | |||||||
| 210 | std::uint64_t | 210 | std::uint64_t | |||||
| HITCBC | 211 | 5 | file_posix:: | 211 | 5 | file_posix:: | ||
| 212 | size( | 212 | size( | |||||
| 213 | system::error_code& ec) const | 213 | system::error_code& ec) const | |||||
| 214 | { | 214 | { | |||||
| HITCBC | 215 | 5 | if(fd_ == -1) | 215 | 5 | if(fd_ == -1) | ||
| 216 | { | 216 | { | |||||
| HITCBC | 217 | 3 | ec = make_error_code( | 217 | 3 | ec = make_error_code( | ||
| 218 | system::errc::bad_file_descriptor); | 218 | system::errc::bad_file_descriptor); | |||||
| HITCBC | 219 | 3 | return 0; | 219 | 3 | return 0; | ||
| 220 | } | 220 | } | |||||
| 221 | struct stat st; | 221 | struct stat st; | |||||
| HITCBC | 222 | 2 | if(::fstat(fd_, &st) != 0) | 222 | 2 | if(::fstat(fd_, &st) != 0) | ||
| 223 | { | 223 | { | |||||
| MISUBC | 224 | ✗ | ec.assign(errno, | 224 | ✗ | ec.assign(errno, | ||
| 225 | system::system_category()); | 225 | system::system_category()); | |||||
| MISUBC | 226 | ✗ | return 0; | 226 | ✗ | return 0; | ||
| 227 | } | 227 | } | |||||
| HITCBC | 228 | 2 | ec = {}; | 228 | 2 | ec = {}; | ||
| HITCBC | 229 | 2 | return st.st_size; | 229 | 2 | return st.st_size; | ||
| 230 | } | 230 | } | |||||
| 231 | 231 | |||||||
| 232 | std::uint64_t | 232 | std::uint64_t | |||||
| HITCBC | 233 | 7 | file_posix:: | 233 | 7 | file_posix:: | ||
| 234 | pos( | 234 | pos( | |||||
| 235 | system::error_code& ec) const | 235 | system::error_code& ec) const | |||||
| 236 | { | 236 | { | |||||
| HITCBC | 237 | 7 | if(fd_ == -1) | 237 | 7 | if(fd_ == -1) | ||
| 238 | { | 238 | { | |||||
| HITCBC | 239 | 3 | ec = make_error_code( | 239 | 3 | ec = make_error_code( | ||
| 240 | system::errc::bad_file_descriptor); | 240 | system::errc::bad_file_descriptor); | |||||
| HITCBC | 241 | 3 | return 0; | 241 | 3 | return 0; | ||
| 242 | } | 242 | } | |||||
| HITCBC | 243 | 4 | auto const result = ::lseek(fd_, 0, SEEK_CUR); | 243 | 4 | auto const result = ::lseek(fd_, 0, SEEK_CUR); | ||
| HITCBC | 244 | 4 | if(result == (::off_t)-1) | 244 | 4 | if(result == (::off_t)-1) | ||
| 245 | { | 245 | { | |||||
| MISUBC | 246 | ✗ | ec.assign(errno, | 246 | ✗ | ec.assign(errno, | ||
| 247 | system::system_category()); | 247 | system::system_category()); | |||||
| MISUBC | 248 | ✗ | return 0; | 248 | ✗ | return 0; | ||
| 249 | } | 249 | } | |||||
| HITCBC | 250 | 4 | ec = {}; | 250 | 4 | ec = {}; | ||
| HITCBC | 251 | 4 | return result; | 251 | 4 | return result; | ||
| 252 | } | 252 | } | |||||
| 253 | 253 | |||||||
| 254 | void | 254 | void | |||||
| HITCBC | 255 | 5 | file_posix:: | 255 | 5 | file_posix:: | ||
| 256 | seek(std::uint64_t offset, | 256 | seek(std::uint64_t offset, | |||||
| 257 | system::error_code& ec) | 257 | system::error_code& ec) | |||||
| 258 | { | 258 | { | |||||
| HITCBC | 259 | 5 | if(fd_ == -1) | 259 | 5 | if(fd_ == -1) | ||
| 260 | { | 260 | { | |||||
| HITCBC | 261 | 3 | ec = make_error_code( | 261 | 3 | ec = make_error_code( | ||
| 262 | system::errc::bad_file_descriptor); | 262 | system::errc::bad_file_descriptor); | |||||
| HITCBC | 263 | 3 | return; | 263 | 3 | return; | ||
| 264 | } | 264 | } | |||||
| HITCBC | 265 | 2 | auto const result = ::lseek(fd_, offset, SEEK_SET); | 265 | 2 | auto const result = ::lseek(fd_, offset, SEEK_SET); | ||
| HITCBC | 266 | 2 | if(result == static_cast<::off_t>(-1)) | 266 | 2 | if(result == static_cast<::off_t>(-1)) | ||
| 267 | { | 267 | { | |||||
| MISUBC | 268 | ✗ | ec.assign(errno, | 268 | ✗ | ec.assign(errno, | ||
| 269 | system::system_category()); | 269 | system::system_category()); | |||||
| MISUBC | 270 | ✗ | return; | 270 | ✗ | return; | ||
| 271 | } | 271 | } | |||||
| HITCBC | 272 | 2 | ec = {}; | 272 | 2 | ec = {}; | ||
| 273 | } | 273 | } | |||||
| 274 | 274 | |||||||
| 275 | std::size_t | 275 | std::size_t | |||||
| HITCBC | 276 | 7 | file_posix:: | 276 | 7 | file_posix:: | ||
| 277 | read(void* buffer, std::size_t n, | 277 | read(void* buffer, std::size_t n, | |||||
| 278 | system::error_code& ec) | 278 | system::error_code& ec) | |||||
| 279 | { | 279 | { | |||||
| HITCBC | 280 | 7 | if(fd_ == -1) | 280 | 7 | if(fd_ == -1) | ||
| 281 | { | 281 | { | |||||
| HITCBC | 282 | 3 | ec = make_error_code( | 282 | 3 | ec = make_error_code( | ||
| 283 | system::errc::bad_file_descriptor); | 283 | system::errc::bad_file_descriptor); | |||||
| HITCBC | 284 | 3 | return 0; | 284 | 3 | return 0; | ||
| 285 | } | 285 | } | |||||
| HITCBC | 286 | 4 | std::size_t nread = 0; | 286 | 4 | std::size_t nread = 0; | ||
| HITCBC | 287 | 8 | while(n > 0) | 287 | 8 | while(n > 0) | ||
| 288 | { | 288 | { | |||||
| 289 | // <limits> not required to define SSIZE_MAX so we avoid it | 289 | // <limits> not required to define SSIZE_MAX so we avoid it | |||||
| HITCBC | 290 | 4 | constexpr auto ssmax = | 290 | 4 | constexpr auto ssmax = | ||
| 291 | static_cast<std::size_t>((std::numeric_limits< | 291 | static_cast<std::size_t>((std::numeric_limits< | |||||
| 292 | decltype(::read(fd_, buffer, n))>::max)()); | 292 | decltype(::read(fd_, buffer, n))>::max)()); | |||||
| HITCBC | 293 | 4 | auto const amount = (std::min)( | 293 | 4 | auto const amount = (std::min)( | ||
| HITCBC | 294 | 4 | n, ssmax); | 294 | 4 | n, ssmax); | ||
| HITCBC | 295 | 4 | auto const result = ::read(fd_, buffer, amount); | 295 | 4 | auto const result = ::read(fd_, buffer, amount); | ||
| HITCBC | 296 | 4 | if(result == -1) | 296 | 4 | if(result == -1) | ||
| 297 | { | 297 | { | |||||
| MISUBC | 298 | ✗ | auto const ev = errno; | 298 | ✗ | auto const ev = errno; | ||
| MISUBC | 299 | ✗ | if(ev == EINTR) | 299 | ✗ | if(ev == EINTR) | ||
| MISUBC | 300 | ✗ | continue; | 300 | ✗ | continue; | ||
| MISUBC | 301 | ✗ | ec.assign(ev, | 301 | ✗ | ec.assign(ev, | ||
| 302 | system::system_category()); | 302 | system::system_category()); | |||||
| MISUBC | 303 | ✗ | return nread; | 303 | ✗ | return nread; | ||
| 304 | } | 304 | } | |||||
| HITCBC | 305 | 4 | if(result == 0) | 305 | 4 | if(result == 0) | ||
| 306 | { | 306 | { | |||||
| 307 | // short read | 307 | // short read | |||||
| MISUBC | 308 | ✗ | return nread; | 308 | ✗ | return nread; | ||
| 309 | } | 309 | } | |||||
| HITCBC | 310 | 4 | n -= result; | 310 | 4 | n -= result; | ||
| HITCBC | 311 | 4 | nread += result; | 311 | 4 | nread += result; | ||
| HITCBC | 312 | 4 | buffer = static_cast<char*>(buffer) + result; | 312 | 4 | buffer = static_cast<char*>(buffer) + result; | ||
| 313 | } | 313 | } | |||||
| HITCBC | 314 | 4 | return nread; | 314 | 4 | return nread; | ||
| 315 | } | 315 | } | |||||
| 316 | 316 | |||||||
| 317 | std::size_t | 317 | std::size_t | |||||
| HITCBC | 318 | 11 | file_posix:: | 318 | 11 | file_posix:: | ||
| 319 | write(void const* buffer, std::size_t n, | 319 | write(void const* buffer, std::size_t n, | |||||
| 320 | system::error_code& ec) | 320 | system::error_code& ec) | |||||
| 321 | { | 321 | { | |||||
| HITCBC | 322 | 11 | if(fd_ == -1) | 322 | 11 | if(fd_ == -1) | ||
| 323 | { | 323 | { | |||||
| HITCBC | 324 | 3 | ec = make_error_code( | 324 | 3 | ec = make_error_code( | ||
| 325 | system::errc::bad_file_descriptor); | 325 | system::errc::bad_file_descriptor); | |||||
| HITCBC | 326 | 3 | return 0; | 326 | 3 | return 0; | ||
| 327 | } | 327 | } | |||||
| HITCBC | 328 | 8 | std::size_t nwritten = 0; | 328 | 8 | std::size_t nwritten = 0; | ||
| HITCBC | 329 | 16 | while(n > 0) | 329 | 16 | while(n > 0) | ||
| 330 | { | 330 | { | |||||
| 331 | // <limits> not required to define SSIZE_MAX so we avoid it | 331 | // <limits> not required to define SSIZE_MAX so we avoid it | |||||
| HITCBC | 332 | 8 | constexpr auto ssmax = | 332 | 8 | constexpr auto ssmax = | ||
| 333 | static_cast<std::size_t>((std::numeric_limits< | 333 | static_cast<std::size_t>((std::numeric_limits< | |||||
| 334 | decltype(::write(fd_, buffer, n))>::max)()); | 334 | decltype(::write(fd_, buffer, n))>::max)()); | |||||
| HITCBC | 335 | 8 | auto const amount = (std::min)( | 335 | 8 | auto const amount = (std::min)( | ||
| HITCBC | 336 | 8 | n, ssmax); | 336 | 8 | n, ssmax); | ||
| HITCBC | 337 | 8 | auto const result = ::write(fd_, buffer, amount); | 337 | 8 | auto const result = ::write(fd_, buffer, amount); | ||
| HITCBC | 338 | 8 | if(result == -1) | 338 | 8 | if(result == -1) | ||
| 339 | { | 339 | { | |||||
| MISUBC | 340 | ✗ | auto const ev = errno; | 340 | ✗ | auto const ev = errno; | ||
| MISUBC | 341 | ✗ | if(ev == EINTR) | 341 | ✗ | if(ev == EINTR) | ||
| MISUBC | 342 | ✗ | continue; | 342 | ✗ | continue; | ||
| MISUBC | 343 | ✗ | ec.assign(ev, | 343 | ✗ | ec.assign(ev, | ||
| 344 | system::system_category()); | 344 | system::system_category()); | |||||
| MISUBC | 345 | ✗ | return nwritten; | 345 | ✗ | return nwritten; | ||
| 346 | } | 346 | } | |||||
| HITCBC | 347 | 8 | n -= result; | 347 | 8 | n -= result; | ||
| HITCBC | 348 | 8 | nwritten += result; | 348 | 8 | nwritten += result; | ||
| HITCBC | 349 | 8 | buffer = static_cast<char const*>(buffer) + result; | 349 | 8 | buffer = static_cast<char const*>(buffer) + result; | ||
| 350 | } | 350 | } | |||||
| HITCBC | 351 | 8 | return nwritten; | 351 | 8 | return nwritten; | ||
| 352 | } | 352 | } | |||||
| 353 | 353 | |||||||
| 354 | } // detail | 354 | } // detail | |||||
| 355 | } // http | 355 | } // http | |||||
| 356 | } // boost | 356 | } // boost | |||||
| 357 | 357 | |||||||
| 358 | #endif | 358 | #endif | |||||