| 1 | // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
|---|
| 2 | // (C) Copyright 2003-2007 Jonathan Turkanis
|
|---|
| 3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|---|
| 4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
|---|
| 5 |
|
|---|
| 6 | // See http://www.boost.org/libs/iostreams for documentation.
|
|---|
| 7 |
|
|---|
| 8 | // Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
|
|---|
| 9 | // knows that we are building the library (possibly exporting code), rather
|
|---|
| 10 | // than using it (possibly importing code).
|
|---|
| 11 | #define BOOST_IOSTREAMS_SOURCE
|
|---|
| 12 |
|
|---|
| 13 | #include <cassert>
|
|---|
| 14 | #include <cerrno>
|
|---|
| 15 | #include <cstdio> // SEEK_SET, etc.
|
|---|
| 16 | #include <boost/config.hpp> // BOOST_JOIN
|
|---|
| 17 | #include <boost/iostreams/detail/error.hpp>
|
|---|
| 18 | #include <boost/iostreams/detail/config/dyn_link.hpp>
|
|---|
| 19 | #include <boost/iostreams/detail/config/rtl.hpp> // BOOST_IOSTREAMS_FD_XXX
|
|---|
| 20 | #include <boost/iostreams/detail/config/windows_posix.hpp>
|
|---|
| 21 | #include <boost/iostreams/detail/system_failure.hpp>
|
|---|
| 22 | #include <boost/iostreams/detail/ios.hpp> // openmodes, failure.
|
|---|
| 23 | #include <boost/iostreams/device/file_descriptor.hpp>
|
|---|
| 24 | #include <boost/integer_traits.hpp>
|
|---|
| 25 | #include <boost/throw_exception.hpp>
|
|---|
| 26 |
|
|---|
| 27 | // OS-specific headers for low-level i/o.
|
|---|
| 28 |
|
|---|
| 29 | #include <fcntl.h> // file opening flags.
|
|---|
| 30 | #include <sys/stat.h> // file access permissions.
|
|---|
| 31 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 32 | # include <io.h> // low-level file i/o.
|
|---|
| 33 | # define WINDOWS_LEAN_AND_MEAN
|
|---|
| 34 | # include <windows.h>
|
|---|
| 35 | # ifndef INVALID_SET_FILE_POINTER
|
|---|
| 36 | # define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
|---|
| 37 | # endif
|
|---|
| 38 | #else
|
|---|
| 39 | # include <sys/types.h> // mode_t.
|
|---|
| 40 | # include <unistd.h> // low-level file i/o.
|
|---|
| 41 | #endif
|
|---|
| 42 |
|
|---|
| 43 | namespace boost { namespace iostreams {
|
|---|
| 44 |
|
|---|
| 45 | //------------------Definition of file_descriptor_impl------------------------//
|
|---|
| 46 |
|
|---|
| 47 | namespace detail {
|
|---|
| 48 |
|
|---|
| 49 | // Contains the platform dependant implementation
|
|---|
| 50 | struct file_descriptor_impl {
|
|---|
| 51 | // Note: These need to match file_desciptor_flags
|
|---|
| 52 | enum flags {
|
|---|
| 53 | never_close = 0,
|
|---|
| 54 | close_on_exit = 1,
|
|---|
| 55 | close_on_close = 2,
|
|---|
| 56 | close_always = 3
|
|---|
| 57 | };
|
|---|
| 58 |
|
|---|
| 59 | file_descriptor_impl();
|
|---|
| 60 | ~file_descriptor_impl();
|
|---|
| 61 | void open(file_handle fd, flags);
|
|---|
| 62 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 63 | void open(int fd, flags);
|
|---|
| 64 | #endif
|
|---|
| 65 | void open(const detail::path&, BOOST_IOS::openmode);
|
|---|
| 66 | bool is_open() const;
|
|---|
| 67 | void close();
|
|---|
| 68 | void close_impl(bool close_flag, bool throw_);
|
|---|
| 69 | std::streamsize read(char* s, std::streamsize n);
|
|---|
| 70 | std::streamsize write(const char* s, std::streamsize n);
|
|---|
| 71 | std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
|
|---|
| 72 | static file_handle invalid_handle();
|
|---|
| 73 | file_handle handle_;
|
|---|
| 74 | int flags_;
|
|---|
| 75 | };
|
|---|
| 76 |
|
|---|
| 77 | //------------------Implementation of file_descriptor_impl--------------------//
|
|---|
| 78 |
|
|---|
| 79 | file_descriptor_impl::file_descriptor_impl()
|
|---|
| 80 | : handle_(invalid_handle()), flags_(0)
|
|---|
| 81 | { }
|
|---|
| 82 |
|
|---|
| 83 | file_descriptor_impl::~file_descriptor_impl()
|
|---|
| 84 | {
|
|---|
| 85 | close_impl(flags_ & close_on_exit, false);
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | void file_descriptor_impl::open(file_handle fd, flags f)
|
|---|
| 89 | {
|
|---|
| 90 | // Using 'close' to close the existing handle so that it will throw an
|
|---|
| 91 | // exception if it fails.
|
|---|
| 92 | //
|
|---|
| 93 | // Only closing after assigning the new handle, so that the class will
|
|---|
| 94 | // take ownership of the handle regardless of whether close throws.
|
|---|
| 95 |
|
|---|
| 96 | file_descriptor_impl tmp;
|
|---|
| 97 | tmp.handle_ = handle_;
|
|---|
| 98 | tmp.flags_ = flags_ & close_on_exit ? close_on_close : never_close;
|
|---|
| 99 |
|
|---|
| 100 | handle_ = fd;
|
|---|
| 101 | flags_ = f;
|
|---|
| 102 |
|
|---|
| 103 | tmp.close();
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 107 |
|
|---|
| 108 | void file_descriptor_impl::open(int fd, flags f)
|
|---|
| 109 | { open(reinterpret_cast<file_handle>(_get_osfhandle(fd)), f); }
|
|---|
| 110 |
|
|---|
| 111 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 112 |
|
|---|
| 113 | void file_descriptor_impl::open(const detail::path& p, BOOST_IOS::openmode mode)
|
|---|
| 114 | {
|
|---|
| 115 | close_impl(flags_ & close_on_exit, true);
|
|---|
| 116 |
|
|---|
| 117 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 118 | DWORD dwDesiredAccess;
|
|---|
| 119 | DWORD dwCreationDisposition;
|
|---|
| 120 | if ( (mode & (BOOST_IOS::in | BOOST_IOS::out))
|
|---|
| 121 | ==
|
|---|
| 122 | (BOOST_IOS::in | BOOST_IOS::out) )
|
|---|
| 123 | {
|
|---|
| 124 | if (mode & BOOST_IOS::app)
|
|---|
| 125 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 126 | dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
|
|---|
| 127 | dwCreationDisposition =
|
|---|
| 128 | (mode & BOOST_IOS::trunc) ?
|
|---|
| 129 | CREATE_ALWAYS :
|
|---|
| 130 | OPEN_EXISTING;
|
|---|
| 131 | } else if (mode & BOOST_IOS::in) {
|
|---|
| 132 | if (mode & (BOOST_IOS::app | BOOST_IOS::trunc))
|
|---|
| 133 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 134 | dwDesiredAccess = GENERIC_READ;
|
|---|
| 135 | dwCreationDisposition = OPEN_EXISTING;
|
|---|
| 136 | } else if (mode & BOOST_IOS::out) {
|
|---|
| 137 | if ( (mode & (BOOST_IOS::app | BOOST_IOS::trunc))
|
|---|
| 138 | ==
|
|---|
| 139 | (BOOST_IOS::app | BOOST_IOS::trunc) )
|
|---|
| 140 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 141 | if (mode & BOOST_IOS::app) {
|
|---|
| 142 | dwCreationDisposition = OPEN_ALWAYS;
|
|---|
| 143 | dwDesiredAccess =
|
|---|
| 144 | FILE_APPEND_DATA |
|
|---|
| 145 | FILE_WRITE_ATTRIBUTES |
|
|---|
| 146 | FILE_WRITE_EA |
|
|---|
| 147 | STANDARD_RIGHTS_WRITE |
|
|---|
| 148 | SYNCHRONIZE;
|
|---|
| 149 | } else {
|
|---|
| 150 | dwDesiredAccess = GENERIC_WRITE;
|
|---|
| 151 | dwCreationDisposition = CREATE_ALWAYS;
|
|---|
| 152 | }
|
|---|
| 153 | } else {
|
|---|
| 154 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 155 | }
|
|---|
| 156 |
|
|---|
| 157 | HANDLE handle = p.is_wide() ?
|
|---|
| 158 | ::CreateFileW( p.c_wstr(),
|
|---|
| 159 | dwDesiredAccess,
|
|---|
| 160 | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|---|
| 161 | NULL, // lpSecurityAttributes
|
|---|
| 162 | dwCreationDisposition,
|
|---|
| 163 | FILE_ATTRIBUTE_NORMAL,
|
|---|
| 164 | NULL ) : // hTemplateFile
|
|---|
| 165 | ::CreateFileA( p.c_str(),
|
|---|
| 166 | dwDesiredAccess,
|
|---|
| 167 | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|---|
| 168 | NULL, // lpSecurityAttributes
|
|---|
| 169 | dwCreationDisposition,
|
|---|
| 170 | FILE_ATTRIBUTE_NORMAL,
|
|---|
| 171 | NULL ); // hTemplateFile
|
|---|
| 172 | if (handle != INVALID_HANDLE_VALUE) {
|
|---|
| 173 | handle_ = handle;
|
|---|
| 174 | flags_ = close_always;
|
|---|
| 175 | } else {
|
|---|
| 176 | flags_ = 0;
|
|---|
| 177 | throw_system_failure("failed opening file");
|
|---|
| 178 | }
|
|---|
| 179 | #else // #ifdef BOOST_IOSTREAMS_WINDOWS //------------------------------------//
|
|---|
| 180 |
|
|---|
| 181 | // Calculate oflag argument to open.
|
|---|
| 182 |
|
|---|
| 183 | int oflag = 0;
|
|---|
| 184 | if ( (mode & (BOOST_IOS::in | BOOST_IOS::out))
|
|---|
| 185 | ==
|
|---|
| 186 | (BOOST_IOS::in | BOOST_IOS::out) )
|
|---|
| 187 | {
|
|---|
| 188 | if( mode & BOOST_IOS::app )
|
|---|
| 189 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 190 | oflag |= O_RDWR;
|
|---|
| 191 | if( mode & BOOST_IOS::trunc ) {
|
|---|
| 192 | oflag |= O_TRUNC;
|
|---|
| 193 | oflag |= O_CREAT;
|
|---|
| 194 | }
|
|---|
| 195 | } else if (mode & BOOST_IOS::in) {
|
|---|
| 196 | if( mode & (BOOST_IOS::app | BOOST_IOS::trunc) )
|
|---|
| 197 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 198 | oflag |= O_RDONLY;
|
|---|
| 199 | } else if (mode & BOOST_IOS::out) {
|
|---|
| 200 | if( (mode & (BOOST_IOS::app | BOOST_IOS::trunc))
|
|---|
| 201 | ==
|
|---|
| 202 | (BOOST_IOS::app | BOOST_IOS::trunc) )
|
|---|
| 203 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 204 | oflag |= O_WRONLY;
|
|---|
| 205 | if (mode & BOOST_IOS::app)
|
|---|
| 206 | oflag |= O_APPEND;
|
|---|
| 207 | else {
|
|---|
| 208 | oflag |= O_CREAT;
|
|---|
| 209 | oflag |= O_TRUNC;
|
|---|
| 210 | }
|
|---|
| 211 | } else {
|
|---|
| 212 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
|
|---|
| 213 | }
|
|---|
| 214 | #ifdef _LARGEFILE64_SOURCE
|
|---|
| 215 | oflag |= O_LARGEFILE;
|
|---|
| 216 | #endif
|
|---|
| 217 |
|
|---|
| 218 | // Calculate pmode argument to open.
|
|---|
| 219 |
|
|---|
| 220 | mode_t pmode = S_IRUSR | S_IWUSR |
|
|---|
| 221 | S_IRGRP | S_IWGRP |
|
|---|
| 222 | S_IROTH | S_IWOTH;
|
|---|
| 223 |
|
|---|
| 224 | // Open file.
|
|---|
| 225 |
|
|---|
| 226 | int fd = BOOST_IOSTREAMS_FD_OPEN(p.c_str(), oflag, pmode);
|
|---|
| 227 | if (fd == -1) {
|
|---|
| 228 | boost::throw_exception(system_failure("failed opening file"));
|
|---|
| 229 | } else {
|
|---|
| 230 | handle_ = fd;
|
|---|
| 231 | flags_ = close_always;
|
|---|
| 232 | }
|
|---|
| 233 | #endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------//
|
|---|
| 234 | }
|
|---|
| 235 |
|
|---|
| 236 | bool file_descriptor_impl::is_open() const
|
|---|
| 237 | { return handle_ != invalid_handle(); }
|
|---|
| 238 |
|
|---|
| 239 | void file_descriptor_impl::close()
|
|---|
| 240 | {
|
|---|
| 241 | close_impl(flags_ & close_on_close, true);
|
|---|
| 242 | }
|
|---|
| 243 |
|
|---|
| 244 | void file_descriptor_impl::close_impl(bool close_flag, bool throw_) {
|
|---|
| 245 | if (handle_ != invalid_handle()) {
|
|---|
| 246 | if (close_flag) {
|
|---|
| 247 | bool success =
|
|---|
| 248 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 249 | ::CloseHandle(handle_) == 1;
|
|---|
| 250 | #else
|
|---|
| 251 | BOOST_IOSTREAMS_FD_CLOSE(handle_) != -1;
|
|---|
| 252 | #endif
|
|---|
| 253 | if (!success && throw_)
|
|---|
| 254 | throw_system_failure("failed closing file");
|
|---|
| 255 | }
|
|---|
| 256 | handle_ = invalid_handle();
|
|---|
| 257 | flags_ = 0;
|
|---|
| 258 | }
|
|---|
| 259 | }
|
|---|
| 260 |
|
|---|
| 261 | std::streamsize file_descriptor_impl::read(char* s, std::streamsize n)
|
|---|
| 262 | {
|
|---|
| 263 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 264 | DWORD result;
|
|---|
| 265 | if (!::ReadFile(handle_, s, n, &result, NULL))
|
|---|
| 266 | {
|
|---|
| 267 | // report EOF if the write-side of a pipe has been closed
|
|---|
| 268 | if (GetLastError() == ERROR_BROKEN_PIPE)
|
|---|
| 269 | {
|
|---|
| 270 | result = 0;
|
|---|
| 271 | }
|
|---|
| 272 | else
|
|---|
| 273 | throw_system_failure("failed reading");
|
|---|
| 274 | }
|
|---|
| 275 | return result == 0 ? -1 : static_cast<std::streamsize>(result);
|
|---|
| 276 | #else // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 277 | errno = 0;
|
|---|
| 278 | std::streamsize result = BOOST_IOSTREAMS_FD_READ(handle_, s, n);
|
|---|
| 279 | if (errno != 0)
|
|---|
| 280 | throw_system_failure("failed reading");
|
|---|
| 281 | return result == 0 ? -1 : result;
|
|---|
| 282 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 283 | }
|
|---|
| 284 |
|
|---|
| 285 | std::streamsize file_descriptor_impl::write(const char* s, std::streamsize n)
|
|---|
| 286 | {
|
|---|
| 287 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 288 | DWORD ignore;
|
|---|
| 289 | if (!::WriteFile(handle_, s, n, &ignore, NULL))
|
|---|
| 290 | throw_system_failure("failed writing");
|
|---|
| 291 | return n;
|
|---|
| 292 | #else // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 293 | int amt = BOOST_IOSTREAMS_FD_WRITE(handle_, s, n);
|
|---|
| 294 | if (amt < n) // Handles blocking fd's only.
|
|---|
| 295 | throw_system_failure("failed writing");
|
|---|
| 296 | return n;
|
|---|
| 297 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 298 | }
|
|---|
| 299 |
|
|---|
| 300 | std::streampos file_descriptor_impl::seek
|
|---|
| 301 | (stream_offset off, BOOST_IOS::seekdir way)
|
|---|
| 302 | {
|
|---|
| 303 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 304 | LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
|
|---|
| 305 | LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
|
|---|
| 306 | DWORD dwResultLow =
|
|---|
| 307 | ::SetFilePointer( handle_,
|
|---|
| 308 | lDistanceToMove,
|
|---|
| 309 | &lDistanceToMoveHigh,
|
|---|
| 310 | way == BOOST_IOS::beg ?
|
|---|
| 311 | FILE_BEGIN :
|
|---|
| 312 | way == BOOST_IOS::cur ?
|
|---|
| 313 | FILE_CURRENT :
|
|---|
| 314 | FILE_END );
|
|---|
| 315 | if ( dwResultLow == INVALID_SET_FILE_POINTER &&
|
|---|
| 316 | ::GetLastError() != NO_ERROR )
|
|---|
| 317 | {
|
|---|
| 318 | boost::throw_exception(system_failure("failed seeking"));
|
|---|
| 319 | } else {
|
|---|
| 320 | return offset_to_position(
|
|---|
| 321 | (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
|
|---|
| 322 | );
|
|---|
| 323 | }
|
|---|
| 324 | #else // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 325 | if ( off > integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_max ||
|
|---|
| 326 | off < integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_min )
|
|---|
| 327 | {
|
|---|
| 328 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset"));
|
|---|
| 329 | }
|
|---|
| 330 | stream_offset result =
|
|---|
| 331 | BOOST_IOSTREAMS_FD_SEEK(
|
|---|
| 332 | handle_,
|
|---|
| 333 | static_cast<BOOST_IOSTREAMS_FD_OFFSET>(off),
|
|---|
| 334 | ( way == BOOST_IOS::beg ?
|
|---|
| 335 | SEEK_SET :
|
|---|
| 336 | way == BOOST_IOS::cur ?
|
|---|
| 337 | SEEK_CUR :
|
|---|
| 338 | SEEK_END )
|
|---|
| 339 | );
|
|---|
| 340 | if (result == -1)
|
|---|
| 341 | boost::throw_exception(system_failure("failed seeking"));
|
|---|
| 342 | return offset_to_position(result);
|
|---|
| 343 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 344 | }
|
|---|
| 345 |
|
|---|
| 346 | // Returns the value stored in a file_handle variable when no file is open
|
|---|
| 347 | file_handle file_descriptor_impl::invalid_handle()
|
|---|
| 348 | {
|
|---|
| 349 | #ifdef BOOST_IOSTREAMS_WINDOWS
|
|---|
| 350 | return INVALID_HANDLE_VALUE;
|
|---|
| 351 | #else
|
|---|
| 352 | return -1;
|
|---|
| 353 | #endif
|
|---|
| 354 | }
|
|---|
| 355 |
|
|---|
| 356 | } // End namespace detail.
|
|---|
| 357 |
|
|---|
| 358 | //------------------Implementation of file_descriptor-------------------------//
|
|---|
| 359 |
|
|---|
| 360 | file_descriptor::file_descriptor() : pimpl_(new impl_type) { }
|
|---|
| 361 |
|
|---|
| 362 | file_descriptor::file_descriptor(handle_type fd, file_descriptor_flags f)
|
|---|
| 363 | : pimpl_(new impl_type)
|
|---|
| 364 | { open(fd, f); }
|
|---|
| 365 |
|
|---|
| 366 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 367 | file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
|
|---|
| 368 | : pimpl_(new impl_type)
|
|---|
| 369 | { open(fd, close_on_exit); }
|
|---|
| 370 | #endif
|
|---|
| 371 |
|
|---|
| 372 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 373 |
|
|---|
| 374 | file_descriptor::file_descriptor(int fd, file_descriptor_flags f)
|
|---|
| 375 | : pimpl_(new impl_type)
|
|---|
| 376 | { open(fd, f); }
|
|---|
| 377 |
|
|---|
| 378 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 379 | file_descriptor::file_descriptor(int fd, bool close_on_exit)
|
|---|
| 380 | : pimpl_(new impl_type)
|
|---|
| 381 | { open(fd, close_on_exit); }
|
|---|
| 382 | #endif
|
|---|
| 383 |
|
|---|
| 384 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 385 |
|
|---|
| 386 | file_descriptor::file_descriptor( const std::string& path,
|
|---|
| 387 | BOOST_IOS::openmode mode )
|
|---|
| 388 | : pimpl_(new impl_type)
|
|---|
| 389 | { open(path, mode); }
|
|---|
| 390 |
|
|---|
| 391 | file_descriptor::file_descriptor( const char* path,
|
|---|
| 392 | BOOST_IOS::openmode mode )
|
|---|
| 393 | : pimpl_(new impl_type)
|
|---|
| 394 | { open(path, mode); }
|
|---|
| 395 |
|
|---|
| 396 | file_descriptor::file_descriptor(const file_descriptor& other)
|
|---|
| 397 | : pimpl_(other.pimpl_)
|
|---|
| 398 | { }
|
|---|
| 399 |
|
|---|
| 400 | void file_descriptor::open(handle_type fd, file_descriptor_flags f)
|
|---|
| 401 | { pimpl_->open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
|
|---|
| 402 |
|
|---|
| 403 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 404 | void file_descriptor::open(handle_type fd, bool close_on_exit)
|
|---|
| 405 | { pimpl_->open(fd, close_on_exit ?
|
|---|
| 406 | detail::file_descriptor_impl::close_always :
|
|---|
| 407 | detail::file_descriptor_impl::close_on_close); }
|
|---|
| 408 | #endif
|
|---|
| 409 |
|
|---|
| 410 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 411 |
|
|---|
| 412 | void file_descriptor::open(int fd, file_descriptor_flags f)
|
|---|
| 413 | { pimpl_->open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
|
|---|
| 414 |
|
|---|
| 415 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 416 | void file_descriptor::open(int fd, bool close_on_exit)
|
|---|
| 417 | { pimpl_->open(fd, close_on_exit ?
|
|---|
| 418 | detail::file_descriptor_impl::close_always :
|
|---|
| 419 | detail::file_descriptor_impl::close_on_close); }
|
|---|
| 420 | #endif
|
|---|
| 421 |
|
|---|
| 422 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 423 |
|
|---|
| 424 | void file_descriptor::open(const std::string& path, BOOST_IOS::openmode mode)
|
|---|
| 425 | { open(detail::path(path), mode); }
|
|---|
| 426 |
|
|---|
| 427 | void file_descriptor::open(const char* path, BOOST_IOS::openmode mode)
|
|---|
| 428 | { open(detail::path(path), mode); }
|
|---|
| 429 |
|
|---|
| 430 | bool file_descriptor::is_open() const { return pimpl_->is_open(); }
|
|---|
| 431 |
|
|---|
| 432 | void file_descriptor::close() { pimpl_->close(); }
|
|---|
| 433 |
|
|---|
| 434 | std::streamsize file_descriptor::read(char_type* s, std::streamsize n)
|
|---|
| 435 | { return pimpl_->read(s, n); }
|
|---|
| 436 |
|
|---|
| 437 | std::streamsize file_descriptor::write(const char_type* s, std::streamsize n)
|
|---|
| 438 | { return pimpl_->write(s, n); }
|
|---|
| 439 |
|
|---|
| 440 | std::streampos file_descriptor::seek(stream_offset off, BOOST_IOS::seekdir way)
|
|---|
| 441 | { return pimpl_->seek(off, way); }
|
|---|
| 442 |
|
|---|
| 443 | detail::file_handle file_descriptor::handle() const { return pimpl_->handle_; }
|
|---|
| 444 |
|
|---|
| 445 | void file_descriptor::init() { pimpl_.reset(new impl_type); }
|
|---|
| 446 |
|
|---|
| 447 | void file_descriptor::open(
|
|---|
| 448 | const detail::path& path,
|
|---|
| 449 | BOOST_IOS::openmode mode,
|
|---|
| 450 | BOOST_IOS::openmode base )
|
|---|
| 451 | {
|
|---|
| 452 | mode |= base;
|
|---|
| 453 | pimpl_->open(path, mode);
|
|---|
| 454 | }
|
|---|
| 455 |
|
|---|
| 456 | //------------------Implementation of file_descriptor_source------------------//
|
|---|
| 457 |
|
|---|
| 458 | file_descriptor_source::file_descriptor_source(
|
|---|
| 459 | handle_type fd, file_descriptor_flags f)
|
|---|
| 460 | { open(fd, f); }
|
|---|
| 461 |
|
|---|
| 462 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 463 | file_descriptor_source::file_descriptor_source(
|
|---|
| 464 | handle_type fd, bool close_on_exit)
|
|---|
| 465 | { open(fd, close_on_exit); }
|
|---|
| 466 | #endif
|
|---|
| 467 |
|
|---|
| 468 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 469 |
|
|---|
| 470 | file_descriptor_source::file_descriptor_source(int fd, file_descriptor_flags f)
|
|---|
| 471 | { open(fd, f); }
|
|---|
| 472 |
|
|---|
| 473 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 474 | file_descriptor_source::file_descriptor_source(int fd, bool close_on_exit)
|
|---|
| 475 | { open(fd, close_on_exit); }
|
|---|
| 476 | #endif
|
|---|
| 477 |
|
|---|
| 478 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 479 |
|
|---|
| 480 | file_descriptor_source::file_descriptor_source(
|
|---|
| 481 | const std::string& path, BOOST_IOS::openmode mode)
|
|---|
| 482 | { open(path, mode); }
|
|---|
| 483 |
|
|---|
| 484 | file_descriptor_source::file_descriptor_source(
|
|---|
| 485 | const char* path, BOOST_IOS::openmode mode)
|
|---|
| 486 | { open(path, mode); }
|
|---|
| 487 |
|
|---|
| 488 | file_descriptor_source::file_descriptor_source(
|
|---|
| 489 | const file_descriptor_source& other)
|
|---|
| 490 | : file_descriptor(static_cast<const file_descriptor&>(other))
|
|---|
| 491 | { }
|
|---|
| 492 |
|
|---|
| 493 | void file_descriptor_source::open(handle_type fd, file_descriptor_flags f)
|
|---|
| 494 | { file_descriptor::open(fd, f); }
|
|---|
| 495 |
|
|---|
| 496 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 497 | void file_descriptor_source::open(handle_type fd, bool close_on_exit)
|
|---|
| 498 | { file_descriptor::open(fd, close_on_exit); }
|
|---|
| 499 | #endif
|
|---|
| 500 |
|
|---|
| 501 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 502 |
|
|---|
| 503 | void file_descriptor_source::open(int fd, file_descriptor_flags f)
|
|---|
| 504 | { file_descriptor::open(fd, f); }
|
|---|
| 505 |
|
|---|
| 506 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 507 | void file_descriptor_source::open(int fd, bool close_on_exit)
|
|---|
| 508 | { file_descriptor::open(fd, close_on_exit); }
|
|---|
| 509 | #endif
|
|---|
| 510 |
|
|---|
| 511 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 512 |
|
|---|
| 513 | void file_descriptor_source::open(
|
|---|
| 514 | const std::string& path, BOOST_IOS::openmode mode)
|
|---|
| 515 | { open(detail::path(path), mode); }
|
|---|
| 516 |
|
|---|
| 517 | void file_descriptor_source::open(
|
|---|
| 518 | const char* path, BOOST_IOS::openmode mode)
|
|---|
| 519 | { open(detail::path(path), mode); }
|
|---|
| 520 |
|
|---|
| 521 | void file_descriptor_source::open(
|
|---|
| 522 | const detail::path& path, BOOST_IOS::openmode mode)
|
|---|
| 523 | {
|
|---|
| 524 | if (mode & (BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc))
|
|---|
| 525 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
|
|---|
| 526 | file_descriptor::open(path, mode, BOOST_IOS::in);
|
|---|
| 527 | }
|
|---|
| 528 |
|
|---|
| 529 | //------------------Implementation of file_descriptor_sink--------------------//
|
|---|
| 530 |
|
|---|
| 531 | file_descriptor_sink::file_descriptor_sink(
|
|---|
| 532 | handle_type fd, file_descriptor_flags f)
|
|---|
| 533 | { open(fd, f); }
|
|---|
| 534 |
|
|---|
| 535 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 536 | file_descriptor_sink::file_descriptor_sink(
|
|---|
| 537 | handle_type fd, bool close_on_exit)
|
|---|
| 538 | { open(fd, close_on_exit); }
|
|---|
| 539 | #endif
|
|---|
| 540 |
|
|---|
| 541 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 542 |
|
|---|
| 543 | file_descriptor_sink::file_descriptor_sink(int fd, file_descriptor_flags f)
|
|---|
| 544 | { open(fd, f); }
|
|---|
| 545 |
|
|---|
| 546 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 547 | file_descriptor_sink::file_descriptor_sink(int fd, bool close_on_exit)
|
|---|
| 548 | { open(fd, close_on_exit); }
|
|---|
| 549 | #endif
|
|---|
| 550 |
|
|---|
| 551 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 552 |
|
|---|
| 553 | file_descriptor_sink::file_descriptor_sink(
|
|---|
| 554 | const std::string& path, BOOST_IOS::openmode mode)
|
|---|
| 555 | { open(path, mode); }
|
|---|
| 556 |
|
|---|
| 557 | file_descriptor_sink::file_descriptor_sink(
|
|---|
| 558 | const char* path, BOOST_IOS::openmode mode)
|
|---|
| 559 | { open(path, mode); }
|
|---|
| 560 |
|
|---|
| 561 | file_descriptor_sink::file_descriptor_sink(const file_descriptor_sink& other)
|
|---|
| 562 | : file_descriptor(static_cast<const file_descriptor&>(other))
|
|---|
| 563 | { }
|
|---|
| 564 |
|
|---|
| 565 | void file_descriptor_sink::open(handle_type fd, file_descriptor_flags f)
|
|---|
| 566 | { file_descriptor::open(fd, f); }
|
|---|
| 567 |
|
|---|
| 568 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 569 | void file_descriptor_sink::open(handle_type fd, bool close_on_exit)
|
|---|
| 570 | { file_descriptor::open(fd, close_on_exit); }
|
|---|
| 571 | #endif
|
|---|
| 572 |
|
|---|
| 573 | #ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
|
|---|
| 574 |
|
|---|
| 575 | void file_descriptor_sink::open(int fd, file_descriptor_flags f)
|
|---|
| 576 | { file_descriptor::open(fd, f); }
|
|---|
| 577 |
|
|---|
| 578 | #if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
|
|---|
| 579 | void file_descriptor_sink::open(int fd, bool close_on_exit)
|
|---|
| 580 | { file_descriptor::open(fd, close_on_exit); }
|
|---|
| 581 | #endif
|
|---|
| 582 |
|
|---|
| 583 | #endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
|
|---|
| 584 |
|
|---|
| 585 | void file_descriptor_sink::open(
|
|---|
| 586 | const std::string& path, BOOST_IOS::openmode mode)
|
|---|
| 587 | { open(detail::path(path), mode); }
|
|---|
| 588 |
|
|---|
| 589 | void file_descriptor_sink::open(
|
|---|
| 590 | const char* path, BOOST_IOS::openmode mode)
|
|---|
| 591 | { open(detail::path(path), mode); }
|
|---|
| 592 |
|
|---|
| 593 | void file_descriptor_sink::open(
|
|---|
| 594 | const detail::path& path, BOOST_IOS::openmode mode)
|
|---|
| 595 | {
|
|---|
| 596 | if (mode & BOOST_IOS::in)
|
|---|
| 597 | boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
|
|---|
| 598 | file_descriptor::open(path, mode, BOOST_IOS::out);
|
|---|
| 599 | }
|
|---|
| 600 |
|
|---|
| 601 | } } // End namespaces iostreams, boost.
|
|---|