////////////////////////////////////////////////////////////////////////////// | |
// | |
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost | |
// Software License, Version 1.0. (See accompanying file | |
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
// See http://www.boost.org/libs/interprocess for documentation. | |
// | |
// Parts of this code are taken from boost::filesystem library | |
// | |
////////////////////////////////////////////////////////////////////////////// | |
// | |
// Copyright (C) 2002 Beman Dawes | |
// Copyright (C) 2001 Dietmar Kuehl | |
// Use, modification, and distribution is subject to the Boost Software | |
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy | |
// at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
// See library home page at http://www.boost.org/libs/filesystem | |
// | |
////////////////////////////////////////////////////////////////////////////// | |
#ifndef BOOST_INTERPROCESS_ERRORS_HPP | |
#define BOOST_INTERPROCESS_ERRORS_HPP | |
#if (defined _MSC_VER) && (_MSC_VER >= 1200) | |
# pragma once | |
#endif | |
#include <boost/interprocess/detail/config_begin.hpp> | |
#include <boost/interprocess/detail/workaround.hpp> | |
#include <stdarg.h> | |
#include <string> | |
#if (defined BOOST_INTERPROCESS_WINDOWS) | |
# include <boost/interprocess/detail/win32_api.hpp> | |
#else | |
# ifdef BOOST_HAS_UNISTD_H | |
# include <errno.h> //Errors | |
# include <cstring> //strerror | |
# else //ifdef BOOST_HAS_UNISTD_H | |
# error Unknown platform | |
# endif //ifdef BOOST_HAS_UNISTD_H | |
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS) | |
//!\file | |
//!Describes the error numbering of interprocess classes | |
namespace boost { | |
namespace interprocess { | |
/// @cond | |
inline int system_error_code() // artifact of POSIX and WINDOWS error reporting | |
{ | |
#if (defined BOOST_INTERPROCESS_WINDOWS) | |
return winapi::get_last_error(); | |
#else | |
return errno; // GCC 3.1 won't accept ::errno | |
#endif | |
} | |
#if (defined BOOST_INTERPROCESS_WINDOWS) | |
inline void fill_system_message(int sys_err_code, std::string &str) | |
{ | |
void *lpMsgBuf; | |
winapi::format_message( | |
winapi::format_message_allocate_buffer | | |
winapi::format_message_from_system | | |
winapi::format_message_ignore_inserts, | |
0, | |
sys_err_code, | |
winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language | |
reinterpret_cast<char *>(&lpMsgBuf), | |
0, | |
0 | |
); | |
str += static_cast<const char*>(lpMsgBuf); | |
winapi::local_free( lpMsgBuf ); // free the buffer | |
while ( str.size() | |
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) | |
str.erase( str.size()-1 ); | |
} | |
# else | |
inline void fill_system_message( int system_error, std::string &str) | |
{ str = std::strerror(system_error); } | |
# endif | |
/// @endcond | |
enum error_code_t | |
{ | |
no_error = 0, | |
system_error, // system generated error; if possible, is translated | |
// to one of the more specific errors below. | |
other_error, // library generated error | |
security_error, // includes access rights, permissions failures | |
read_only_error, | |
io_error, | |
path_error, | |
not_found_error, | |
// not_directory_error, | |
busy_error, // implies trying again might succeed | |
already_exists_error, | |
not_empty_error, | |
is_directory_error, | |
out_of_space_error, | |
out_of_memory_error, | |
out_of_resource_error, | |
lock_error, | |
sem_error, | |
mode_error, | |
size_error, | |
corrupted_error, | |
not_such_file_or_directory, | |
invalid_argument | |
}; | |
typedef int native_error_t; | |
/// @cond | |
struct ec_xlate | |
{ | |
native_error_t sys_ec; | |
error_code_t ec; | |
}; | |
static const ec_xlate ec_table[] = | |
{ | |
#if (defined BOOST_INTERPROCESS_WINDOWS) | |
{ /*ERROR_ACCESS_DENIED*/5L, security_error }, | |
{ /*ERROR_INVALID_ACCESS*/12L, security_error }, | |
{ /*ERROR_SHARING_VIOLATION*/32L, security_error }, | |
{ /*ERROR_LOCK_VIOLATION*/33L, security_error }, | |
{ /*ERROR_LOCKED*/212L, security_error }, | |
{ /*ERROR_NOACCESS*/998L, security_error }, | |
{ /*ERROR_WRITE_PROTECT*/19L, read_only_error }, | |
{ /*ERROR_NOT_READY*/21L, io_error }, | |
{ /*ERROR_SEEK*/25L, io_error }, | |
{ /*ERROR_READ_FAULT*/30L, io_error }, | |
{ /*ERROR_WRITE_FAULT*/29L, io_error }, | |
{ /*ERROR_CANTOPEN*/1011L, io_error }, | |
{ /*ERROR_CANTREAD*/1012L, io_error }, | |
{ /*ERROR_CANTWRITE*/1013L, io_error }, | |
{ /*ERROR_DIRECTORY*/267L, path_error }, | |
{ /*ERROR_INVALID_NAME*/123L, path_error }, | |
{ /*ERROR_FILE_NOT_FOUND*/2L, not_found_error }, | |
{ /*ERROR_PATH_NOT_FOUND*/3L, not_found_error }, | |
{ /*ERROR_DEV_NOT_EXIST*/55L, not_found_error }, | |
{ /*ERROR_DEVICE_IN_USE*/2404L, busy_error }, | |
{ /*ERROR_OPEN_FILES*/2401L, busy_error }, | |
{ /*ERROR_BUSY_DRIVE*/142L, busy_error }, | |
{ /*ERROR_BUSY*/170L, busy_error }, | |
{ /*ERROR_FILE_EXISTS*/80L, already_exists_error }, | |
{ /*ERROR_ALREADY_EXISTS*/183L, already_exists_error }, | |
{ /*ERROR_DIR_NOT_EMPTY*/145L, not_empty_error }, | |
{ /*ERROR_HANDLE_DISK_FULL*/39L, out_of_space_error }, | |
{ /*ERROR_DISK_FULL*/112L, out_of_space_error }, | |
{ /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error }, | |
{ /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error }, | |
{ /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error } | |
#else //#if (defined BOOST_INTERPROCESS_WINDOWS) | |
{ EACCES, security_error }, | |
{ EROFS, read_only_error }, | |
{ EIO, io_error }, | |
{ ENAMETOOLONG, path_error }, | |
{ ENOENT, not_found_error }, | |
// { ENOTDIR, not_directory_error }, | |
{ EAGAIN, busy_error }, | |
{ EBUSY, busy_error }, | |
{ ETXTBSY, busy_error }, | |
{ EEXIST, already_exists_error }, | |
{ ENOTEMPTY, not_empty_error }, | |
{ EISDIR, is_directory_error }, | |
{ ENOSPC, out_of_space_error }, | |
{ ENOMEM, out_of_memory_error }, | |
{ EMFILE, out_of_resource_error }, | |
{ ENOENT, not_such_file_or_directory }, | |
{ EINVAL, invalid_argument } | |
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS) | |
}; | |
inline error_code_t lookup_error(native_error_t err) | |
{ | |
const ec_xlate *cur = &ec_table[0], | |
*end = cur + sizeof(ec_table)/sizeof(ec_xlate); | |
for (;cur != end; ++cur ){ | |
if ( err == cur->sys_ec ) return cur->ec; | |
} | |
return system_error; // general system error code | |
} | |
struct error_info | |
{ | |
error_info(error_code_t ec = other_error ) | |
: m_nat(0), m_ec(ec) | |
{} | |
error_info(native_error_t sys_err_code) | |
: m_nat(sys_err_code), m_ec(lookup_error(sys_err_code)) | |
{} | |
error_info & operator =(error_code_t ec) | |
{ | |
m_nat = 0; | |
m_ec = ec; | |
return *this; | |
} | |
error_info & operator =(native_error_t sys_err_code) | |
{ | |
m_nat = sys_err_code; | |
m_ec = lookup_error(sys_err_code); | |
return *this; | |
} | |
native_error_t get_native_error()const | |
{ return m_nat; } | |
error_code_t get_error_code()const | |
{ return m_ec; } | |
private: | |
native_error_t m_nat; | |
error_code_t m_ec; | |
}; | |
/// @endcond | |
} // namespace interprocess { | |
} // namespace boost | |
#include <boost/interprocess/detail/config_end.hpp> | |
#endif // BOOST_INTERPROCESS_ERRORS_HPP |