static void do_open(Fstream& s, const Path& path, const std::ios_base::openmode mode, typename boost::enable_if<fs::is_basic_path<Path> >::type* = 0) { try { if (!allow_read(path)) throw system_error(error_code(EACCES, get_system_category())); stream_do_open(s, path, mode); if (!s.is_open()) throw system_error(error_code(errno, get_system_category())); } catch (const system_error& e) { string what(e.std::runtime_error::what()); if (!what.empty()) what = ": " + what; what = rwu_error_message(s) + what; throw fs::filesystem_error(what, path, e.code()); } }
inline bool connections::doHandShake(connection* c, handshake f, void* data) { bool ret = true; try { // 1.0 - 2.1 namepd pipe is not HandShakable. if (c->isHandShakable()) { if (!f) c->read(); else ret = f(c, data); if (c->error()) m_e = asio::error::connection_refused; else if (!ret) m_e = asio::error::no_permission; if (!ret) delete c; } return ret; } catch (bzs::netsvc::client::exception& e) { delete c; m_e = boost::system::error_code(e.error(), get_system_category()); return false; } catch (boost::system::system_error& e) { m_e = e.code(); delete c; return false; } }
static bool allow_readwrite(const boost::filesystem::path& path, const unsigned int recursion) { if (recursion > SYMLOOP_MAX) throw system_error(error_code(ELOOP, get_system_category())); const bool symlink = fs::is_symlink(path); for (vector<fs::path>::const_iterator dir = allowed_readwrite_paths.begin(); dir != allowed_readwrite_paths.end(); ++dir) if (dir_contains_path(*dir, path)) return symlink ? allow_readwrite(readlink(path), recursion + 1) : true; for (vector<fs::path>::const_iterator dir = allowed_read_paths.begin(); dir != allowed_read_paths.end(); ++dir) if (dir_contains_path(*dir, path)) return symlink ? allow_readwrite(readlink(path), recursion + 1) : true; return false; }
inline connection* connections::doConnect(connection* c) { try { c->connect(); if (c->isConnected()) return c; m_e = c->error(); delete c; return NULL; } catch (bzs::netsvc::client::exception& e) { m_e = boost::system::error_code(e.error(), get_system_category()); delete c; return NULL; } catch (boost::system::system_error& e) { m_e = e.code(); delete c; return NULL; } catch (std::exception& /*e*/) { m_e = boost::system::error_code(1, get_system_category()); delete c; return NULL; } catch (...) { m_e = boost::system::error_code(1, get_system_category()); delete c; return NULL; } }
size_type file::get_size(error_code& ec) const { #ifdef TORRENT_WINDOWS LARGE_INTEGER file_size; if (!GetFileSizeEx(m_file_handle, &file_size)) { ec = error_code(GetLastError(), get_system_category()); return -1; } return file_size.QuadPart; #else struct stat fs; if (fstat(m_fd, &fs) != 0) { ec = error_code(errno, get_posix_category()); return -1; } return fs.st_size; #endif }
inline const autoboost::system::error_category& get_netdb_category() { return get_system_category(); }
bool file::set_size(size_type s, error_code& ec) { TORRENT_ASSERT(is_open()); TORRENT_ASSERT(s >= 0); #ifdef TORRENT_WINDOWS LARGE_INTEGER offs; LARGE_INTEGER cur_size; if (GetFileSizeEx(m_file_handle, &cur_size) == FALSE) { ec = error_code(GetLastError(), get_system_category()); return false; } offs.QuadPart = s; // only set the file size if it's not already at // the right size. We don't want to update the // modification time if we don't have to if (cur_size.QuadPart != s) { if (SetFilePointerEx(m_file_handle, offs, &offs, FILE_BEGIN) == FALSE) { ec.assign(GetLastError(), get_system_category()); return false; } if (::SetEndOfFile(m_file_handle) == FALSE) { ec.assign(GetLastError(), get_system_category()); return false; } } #if _WIN32_WINNT >= 0x501 if ((m_open_mode & sparse) == 0) { // only allocate the space if the file // is not fully allocated DWORD high_dword = 0; offs.LowPart = GetCompressedFileSize(m_path.c_str(), &high_dword); offs.HighPart = high_dword; ec.assign(GetLastError(), get_system_category()); if (ec) return false; if (offs.QuadPart != s) { // if the user has permissions, avoid filling // the file with zeroes, but just fill it with // garbage instead SetFileValidData(m_file_handle, offs.QuadPart); } } #endif // _WIN32_WINNT >= 0x501 #else // NON-WINDOWS struct stat st; if (fstat(m_fd, &st) != 0) { ec.assign(errno, get_posix_category()); return false; } // only truncate the file if it doesn't already // have the right size. We don't want to update if (st.st_size != s && ftruncate(m_fd, s) < 0) { ec.assign(errno, get_posix_category()); return false; } // if we're not in sparse mode, allocate the storage // but only if the number of allocated blocks for the file // is less than the file size. Otherwise we would just // update the modification time of the file for no good // reason. if ((m_open_mode & sparse) == 0 && st.st_blocks < (s + st.st_blksize - 1) / st.st_blksize) { // How do we know that the file is already allocated? // if we always try to allocate the space, we'll update // the modification time without actually changing the file // but if we don't do anything if the file size is #ifdef F_PREALLOCATE fstore_t f = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, s, 0}; if (fcntl(m_fd, F_PREALLOCATE, &f) < 0) { ec = error_code(errno, get_posix_category()); return false; } #endif // F_PREALLOCATE #if defined TORRENT_LINUX || TORRENT_HAS_FALLOCATE int ret; #endif #if defined TORRENT_LINUX ret = my_fallocate(m_fd, 0, 0, s); // if we return 0, everything went fine // the fallocate call succeeded if (ret == 0) return true; // otherwise, something went wrong. If the error // is ENOSYS, just keep going and do it the old-fashioned // way. If fallocate failed with some other error, it // probably means the user should know about it, error out // and report it. if (errno != ENOSYS && errno != EOPNOTSUPP) { ec.assign(errno, get_posix_category()); return false; } #endif // TORRENT_LINUX #if TORRENT_HAS_FALLOCATE // if fallocate failed, we have to use posix_fallocate // which can be painfully slow // if you get a compile error here, you might want to // define TORRENT_HAS_FALLOCATE to 0. ret = posix_fallocate(m_fd, 0, s); // posix_allocate fails with EINVAL in case the underlying // filesystem does bot support this operation if (ret != 0 && ret != EINVAL) { ec = error_code(ret, get_posix_category()); return false; } #endif // TORRENT_HAS_FALLOCATE } #endif // TORRENT_WINDOWS return true; }
size_type file::writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec) { TORRENT_ASSERT((m_open_mode & rw_mask) == write_only || (m_open_mode & rw_mask) == read_write); TORRENT_ASSERT(bufs); TORRENT_ASSERT(num_bufs > 0); TORRENT_ASSERT(is_open()); #if defined TORRENT_WINDOWS || defined TORRENT_LINUX || defined TORRENT_DEBUG // make sure m_page_size is initialized init_file(); #endif #ifdef TORRENT_DEBUG if (m_open_mode & no_buffer) { bool eof = false; int size = 0; // when opened in no_buffer mode, the file_offset must // be aligned to pos_alignment() TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0); for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) { TORRENT_ASSERT((uintptr_t(i->iov_base) & (buf_alignment()-1)) == 0); // every buffer must be a multiple of the page size // except for the last one TORRENT_ASSERT((i->iov_len & (size_alignment()-1)) == 0 || i == end-1); if ((i->iov_len & (size_alignment()-1)) != 0) eof = true; size += i->iov_len; } error_code code; if (eof) TORRENT_ASSERT(file_offset + size >= get_size(code)); } #endif #ifdef TORRENT_WINDOWS DWORD ret = 0; // since the ReadFileScatter requires the file to be opened // with no buffering, and no buffering requires page aligned // buffers, open the file in non-buffered mode in case the // buffer is not aligned. Most of the times the buffer should // be aligned though if ((m_open_mode & no_buffer) == 0) { // this means the buffer base or the buffer size is not aligned // to the page size. Use a regular file for this operation. LARGE_INTEGER offs; offs.QuadPart = file_offset; if (SetFilePointerEx(m_file_handle, offs, &offs, FILE_BEGIN) == FALSE) { ec = error_code(GetLastError(), get_system_category()); return -1; } for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) { DWORD intermediate = 0; if (WriteFile(m_file_handle, (char const*)i->iov_base , (DWORD)i->iov_len, &intermediate, 0) == FALSE) { ec = error_code(GetLastError(), get_system_category()); return -1; } ret += intermediate; } return ret; } int size = bufs_size(bufs, num_bufs); // number of pages for the write. round up int num_pages = (size + m_page_size - 1) / m_page_size; // allocate array of FILE_SEGMENT_ELEMENT for WriteFileGather FILE_SEGMENT_ELEMENT* segment_array = TORRENT_ALLOCA(FILE_SEGMENT_ELEMENT, num_pages + 1); FILE_SEGMENT_ELEMENT* cur_seg = segment_array; for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) { for (int k = 0; k < i->iov_len; k += m_page_size) { cur_seg->Buffer = PtrToPtr64((((char*)i->iov_base) + k)); ++cur_seg; } } // terminate the array cur_seg->Buffer = 0; OVERLAPPED ol; ol.Internal = 0; ol.InternalHigh = 0; ol.OffsetHigh = file_offset >> 32; ol.Offset = file_offset & 0xffffffff; ol.hEvent = CreateEvent(0, true, false, 0); ret += size; // if file_size is > 0, the file will be opened in unbuffered // mode after the write completes, and truncate the file to // file_size. size_type file_size = 0; if ((size & (m_page_size-1)) != 0) { // if size is not an even multiple, this must be the tail // of the file. Write the whole page and then open a new // file without FILE_FLAG_NO_BUFFERING and set the // file size to file_offset + size file_size = file_offset + size; size = num_pages * m_page_size; } if (WriteFileGather(m_file_handle, segment_array, size, 0, &ol) == 0) { if (GetLastError() != ERROR_IO_PENDING) { TORRENT_ASSERT(GetLastError() != ERROR_BAD_ARGUMENTS); ec = error_code(GetLastError(), get_system_category()); CloseHandle(ol.hEvent); return -1; } DWORD tmp; if (GetOverlappedResult(m_file_handle, &ol, &tmp, true) == 0) { ec = error_code(GetLastError(), get_system_category()); CloseHandle(ol.hEvent); return -1; } if (tmp < ret) ret = tmp; } CloseHandle(ol.hEvent); if (file_size > 0) { #if TORRENT_USE_WPATH #define CreateFile_ CreateFileW #else #define CreateFile_ CreateFileA #endif HANDLE f = CreateFile_(m_path.c_str(), GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0); if (f == INVALID_HANDLE_VALUE) { ec = error_code(GetLastError(), get_system_category()); return -1; } LARGE_INTEGER offs; offs.QuadPart = file_size; if (SetFilePointerEx(f, offs, &offs, FILE_BEGIN) == FALSE) { CloseHandle(f); ec = error_code(GetLastError(), get_system_category()); return -1; } if (::SetEndOfFile(f) == FALSE) { ec = error_code(GetLastError(), get_system_category()); CloseHandle(f); return -1; } CloseHandle(f); } return ret; #else size_type ret = lseek(m_fd, file_offset, SEEK_SET); if (ret < 0) { ec = error_code(errno, get_posix_category()); return -1; } #if TORRENT_USE_WRITEV #ifdef TORRENT_LINUX bool aligned = false; int size = 0; // if we're not opened in no-buffer mode, we don't need alignment if ((m_open_mode & no_buffer) == 0) aligned = true; if (!aligned) { size = bufs_size(bufs, num_bufs); if ((size & (size_alignment()-1)) == 0) aligned = true; } if (aligned) #endif { ret = ::writev(m_fd, bufs, num_bufs); if (ret < 0) { ec = error_code(errno, get_posix_category()); return -1; } return ret; } #ifdef TORRENT_LINUX file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs); memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs); iovec_t& last = temp_bufs[num_bufs-1]; last.iov_len = (last.iov_len & ~(size_alignment()-1)) + size_alignment(); ret = ::writev(m_fd, temp_bufs, num_bufs); if (ret < 0) { ec = error_code(errno, get_posix_category()); return -1; } if (ftruncate(m_fd, file_offset + size) < 0) { ec = error_code(errno, get_posix_category()); return -1; } return (std::min)(ret, size_type(size)); #endif // TORRENT_LINUX #else // TORRENT_USE_WRITEV ret = 0; for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) { int tmp = write(m_fd, i->iov_base, i->iov_len); if (tmp < 0) { ec = error_code(errno, get_posix_category()); return -1; } ret += tmp; if (tmp < i->iov_len) break; } return ret; #endif // TORRENT_USE_WRITEV #endif // TORRENT_WINDOWS }
inline error_code make_error_code( windows_error_code e ) { return error_code( e, get_system_category() ); }
inline const asio::error_category& get_addrinfo_category() { return get_system_category(); }
inline const asio::error_category& get_netdb_category() { return get_system_category(); }
inline error_code make_error_code( linux_errno e ) { return error_code( e, get_system_category() ); }
namespace system { class error_code; class error_condition; // "Concept" helpers ---------------------------------------------------// template< class T > struct is_error_code_enum { static const bool value = false; }; template< class T > struct is_error_condition_enum { static const bool value = false; }; // generic error_conditions --------------------------------------------// namespace errc { enum errc_t { success = 0, address_family_not_supported = EAFNOSUPPORT, address_in_use = EADDRINUSE, address_not_available = EADDRNOTAVAIL, already_connected = EISCONN, argument_list_too_long = E2BIG, argument_out_of_domain = EDOM, bad_address = EFAULT, bad_file_descriptor = EBADF, bad_message = EBADMSG, broken_pipe = EPIPE, connection_aborted = ECONNABORTED, connection_already_in_progress = EALREADY, connection_refused = ECONNREFUSED, connection_reset = ECONNRESET, cross_device_link = EXDEV, destination_address_required = EDESTADDRREQ, device_or_resource_busy = EBUSY, directory_not_empty = ENOTEMPTY, executable_format_error = ENOEXEC, file_exists = EEXIST, file_too_large = EFBIG, filename_too_long = ENAMETOOLONG, function_not_supported = ENOSYS, host_unreachable = EHOSTUNREACH, identifier_removed = EIDRM, illegal_byte_sequence = EILSEQ, inappropriate_io_control_operation = ENOTTY, interrupted = EINTR, invalid_argument = EINVAL, invalid_seek = ESPIPE, io_error = EIO, is_a_directory = EISDIR, message_size = EMSGSIZE, network_down = ENETDOWN, network_reset = ENETRESET, network_unreachable = ENETUNREACH, no_buffer_space = ENOBUFS, no_child_process = ECHILD, no_link = ENOLINK, no_lock_available = ENOLCK, no_message_available = ENODATA, no_message = ENOMSG, no_protocol_option = ENOPROTOOPT, no_space_on_device = ENOSPC, no_stream_resources = ENOSR, no_such_device_or_address = ENXIO, no_such_device = ENODEV, no_such_file_or_directory = ENOENT, no_such_process = ESRCH, not_a_directory = ENOTDIR, not_a_socket = ENOTSOCK, not_a_stream = ENOSTR, not_connected = ENOTCONN, not_enough_memory = ENOMEM, not_supported = ENOTSUP, operation_canceled = ECANCELED, operation_in_progress = EINPROGRESS, operation_not_permitted = EPERM, operation_not_supported = EOPNOTSUPP, operation_would_block = EWOULDBLOCK, owner_dead = EOWNERDEAD, permission_denied = EACCES, protocol_error = EPROTO, protocol_not_supported = EPROTONOSUPPORT, read_only_file_system = EROFS, resource_deadlock_would_occur = EDEADLK, resource_unavailable_try_again = EAGAIN, result_out_of_range = ERANGE, state_not_recoverable = ENOTRECOVERABLE, stream_timeout = ETIME, text_file_busy = ETXTBSY, timed_out = ETIMEDOUT, too_many_files_open_in_system = ENFILE, too_many_files_open = EMFILE, too_many_links = EMLINK, too_many_synbolic_link_levels = ELOOP, value_too_large = EOVERFLOW, wrong_protocol_type = EPROTOTYPE }; } // namespace errc # ifndef BOOST_SYSTEM_NO_DEPRECATED namespace posix = errc; namespace posix_error = errc; # endif template<> struct is_error_condition_enum<errc::errc_t> { static const bool value = true; }; // ----------------------------------------------------------------------// // Operating system specific interfaces --------------------------------// // The interface is divided into general and system-specific portions to // meet these requirements: // // * Code calling an operating system API can create an error_code with // a single category (system_category), even for POSIX-like operating // systems that return some POSIX errno values and some native errno // values. This code should not have to pay the cost of distinguishing // between categories, since it is not yet known if that is needed. // // * Users wishing to write system-specific code should be given enums for // at least the common error cases. // // * System specific code should fail at compile time if moved to another // operating system. // The system specific portions of the interface are located in headers // with names reflecting the operating system. For example, // // <boost/system/cygwin_error.hpp> // <boost/system/linux_error.hpp> // <boost/system/windows_error.hpp> // // These headers are effectively empty for compiles on operating systems // where they are not applicable. // ----------------------------------------------------------------------// // class error_category ------------------------------------------------// class error_category : public noncopyable { public: virtual ~error_category(){} virtual inline const char * name() const; // see implementation note below virtual inline std::string message( int ev ) const; // see implementation note below virtual inline error_condition default_error_condition( int ev ) const; virtual inline bool equivalent( int code, const error_condition & condition ) const; virtual inline bool equivalent( const error_code & code, int condition ) const; bool operator==(const error_category & rhs) const { return this == &rhs; } bool operator!=(const error_category & rhs) const { return this != &rhs; } bool operator<( const error_category & rhs ) const { return std::less<const error_category*>()( this, &rhs ); } }; // predefined error categories -----------------------------------------// BOOST_SYSTEM_DECL const error_category & get_system_category(); BOOST_SYSTEM_DECL const error_category & get_generic_category(); static const error_category & system_category = get_system_category(); static const error_category & generic_category = get_generic_category(); # ifndef BOOST_SYSTEM_NO_DEPRECATED // deprecated synonyms static const error_category & posix_category = get_generic_category(); static const error_category & errno_ecat = get_generic_category(); static const error_category & native_ecat = get_system_category(); # endif // class error_condition -----------------------------------------------// // error_conditions are portable, error_codes are system or lib specific class error_condition { public: // constructors: error_condition() : m_val(0), m_cat(&get_generic_category()) {} error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template <class ConditionEnum> error_condition(ConditionEnum e, typename boost::enable_if<is_error_condition_enum<ConditionEnum> >::type* = 0) { *this = make_error_condition(e); } // modifiers: void assign( int val, const error_category & cat ) { m_val = val; m_cat = &cat; } template<typename ConditionEnum> typename boost::enable_if<is_error_condition_enum<ConditionEnum>, error_condition>::type & operator=( ConditionEnum val ) { *this = make_error_condition(val); return *this; } void clear() { m_val = 0; m_cat = &get_generic_category(); } // observers: int value() const { return m_val; } const error_category & category() const { return *m_cat; } std::string message() const { return m_cat->message(value()); } typedef void (*unspecified_bool_type)(); static void unspecified_bool_true() {} operator unspecified_bool_type() const // true if error { return m_val == 0 ? 0 : unspecified_bool_true; } bool operator!() const // true if no error { return m_val == 0; } // relationals: // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) { return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; } inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. { return lhs.m_cat < rhs.m_cat || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); } private: int m_val; const error_category * m_cat; }; // class error_code ----------------------------------------------------// // We want error_code to be a value type that can be copied without slicing // and without requiring heap allocation, but we also want it to have // polymorphic behavior based on the error category. This is achieved by // abstract base class error_category supplying the polymorphic behavior, // and error_code containing a pointer to an object of a type derived // from error_category. class error_code { public: // constructors: error_code() : m_val(0), m_cat(&get_system_category()) {} error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template <class CodeEnum> error_code(CodeEnum e, typename boost::enable_if<is_error_code_enum<CodeEnum> >::type* = 0) { *this = make_error_code(e); } // modifiers: void assign( int val, const error_category & cat ) { m_val = val; m_cat = &cat; } template<typename CodeEnum> typename boost::enable_if<is_error_code_enum<CodeEnum>, error_code>::type & operator=( CodeEnum val ) { *this = make_error_code(val); return *this; } void clear() { m_val = 0; m_cat = &get_system_category(); } // observers: int value() const { return m_val; } const error_category & category() const { return *m_cat; } error_condition default_error_condition() const { return m_cat->default_error_condition(value()); } std::string message() const { return m_cat->message(value()); } typedef void (*unspecified_bool_type)(); static void unspecified_bool_true() {} operator unspecified_bool_type() const // true if error { return m_val == 0 ? 0 : unspecified_bool_true; } bool operator!() const // true if no error { return m_val == 0; } // relationals: inline friend bool operator==( const error_code & lhs, const error_code & rhs ) // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. { return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; } inline friend bool operator<( const error_code & lhs, const error_code & rhs ) // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. { return lhs.m_cat < rhs.m_cat || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); } private: int m_val; const error_category * m_cat; }; // non-member functions ------------------------------------------------// inline bool operator!=( const error_code & lhs, const error_code & rhs ) { return !(lhs == rhs); } inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) { return !(lhs == rhs); } inline bool operator==( const error_code & code, const error_condition & condition ) { return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() ); } inline bool operator!=( const error_code & lhs, const error_condition & rhs ) { return !(lhs == rhs); } inline bool operator==( const error_condition & condition, const error_code & code ) { return condition.category().equivalent( code, condition.value() ) || code.category().equivalent( code.value(), condition ); } inline bool operator!=( const error_condition & lhs, const error_code & rhs ) { return !(lhs == rhs); } // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet. template <class charT, class traits> inline std::basic_ostream<charT,traits>& operator<< (std::basic_ostream<charT,traits>& os, error_code ec) { os << ec.category().name() << ':' << ec.value(); return os; } inline std::size_t hash_value( const error_code & ec ) { return static_cast<std::size_t>(ec.value()) + reinterpret_cast<std::size_t>(&ec.category()); } // make_* functions for errc::errc_t -----------------------------// namespace errc { // explicit conversion: inline error_code make_error_code( errc_t e ) { return error_code( e, get_generic_category() ); } // implicit conversion: inline error_condition make_error_condition( errc_t e ) { return error_condition( e, get_generic_category() ); } } // error_category default implementation -------------------------------// inline error_condition error_category::default_error_condition( int ev ) const { return error_condition( ev, *this ); } inline bool error_category::equivalent( int code, const error_condition & condition ) const { return default_error_condition( code ) == condition; } inline bool error_category::equivalent( const error_code & code, int condition ) const { return *this == code.category() && code.value() == condition; } // error_category implementation note: VC++ 8.0 objects to name() and // message() being pure virtual functions. Thus these implementations. inline const char * error_category::name() const { return "error: should never be called"; } inline std::string error_category::message( int ) const { static std::string s("error: should never be called"); return s; } } // namespace system
void clear() { m_val = 0; m_cat = &get_system_category(); }
// constructors: error_code() : m_val(0), m_cat(&get_system_category()) {}
inline const autoboost::system::error_category& get_addrinfo_category() { return get_system_category(); }
inline asio::error_code make_error_code(basic_errors e) { return asio::error_code( static_cast<int>(e), get_system_category()); }
inline riakboost::system::error_code make_error_code(basic_errors e) { return riakboost::system::error_code( static_cast<int>(e), get_system_category()); }