1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 // Parts of this code are taken from boost::filesystem library
10 //
11 //////////////////////////////////////////////////////////////////////////////
12 //
13 //  Copyright (C) 2002 Beman Dawes
14 //  Copyright (C) 2001 Dietmar Kuehl
15 //  Use, modification, and distribution is subject to the Boost Software
16 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
17 //  at http://www.boost.org/LICENSE_1_0.txt)
18 //
19 //  See library home page at http://www.boost.org/libs/filesystem
20 //
21 //////////////////////////////////////////////////////////////////////////////
22 
23 
24 #ifndef BOOST_INTERPROCESS_ERRORS_HPP
25 #define BOOST_INTERPROCESS_ERRORS_HPP
26 
27 #ifndef BOOST_CONFIG_HPP
28 #  include <boost/config.hpp>
29 #endif
30 #
31 #if defined(BOOST_HAS_PRAGMA_ONCE)
32 #  pragma once
33 #endif
34 
35 #include <boost/interprocess/detail/config_begin.hpp>
36 #include <boost/interprocess/detail/workaround.hpp>
37 #include <string>
38 
39 #if defined (BOOST_INTERPROCESS_WINDOWS)
40 #  include <boost/interprocess/detail/win32_api.hpp>
41 #else
42 #  ifdef BOOST_HAS_UNISTD_H
43 #    include <cerrno>         //Errors
44 #    include <cstring>        //strerror
45 #  else  //ifdef BOOST_HAS_UNISTD_H
46 #    error Unknown platform
47 #  endif //ifdef BOOST_HAS_UNISTD_H
48 #endif   //#if defined (BOOST_INTERPROCESS_WINDOWS)
49 
50 //!\file
51 //!Describes the error numbering of interprocess classes
52 
53 namespace boost {
54 namespace interprocess {
55 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
system_error_code()56 inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
57 {
58    #if defined (BOOST_INTERPROCESS_WINDOWS)
59    return (int)winapi::get_last_error();
60    #else
61    return errno; // GCC 3.1 won't accept ::errno
62    #endif
63 }
64 
65 
66 #if defined (BOOST_INTERPROCESS_WINDOWS)
fill_system_message(int sys_err_code,std::string & str)67 inline void fill_system_message(int sys_err_code, std::string &str)
68 {
69    void *lpMsgBuf;
70    unsigned long ret = winapi::format_message(
71       winapi::format_message_allocate_buffer |
72       winapi::format_message_from_system |
73       winapi::format_message_ignore_inserts,
74       0,
75       (unsigned long)sys_err_code,
76       winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language
77       reinterpret_cast<char *>(&lpMsgBuf),
78       0,
79       0
80    );
81    if (ret != 0){
82       str += static_cast<const char*>(lpMsgBuf);
83       winapi::local_free( lpMsgBuf ); // free the buffer
84       while ( str.size()
85          && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
86          str.erase( str.size()-1 );
87    }
88    else{
89       str += "WinApi FormatMessage returned error";
90    }
91 }
92 # else
fill_system_message(int system_error,std::string & str)93 inline void fill_system_message( int system_error, std::string &str)
94 {  str = std::strerror(system_error);  }
95 # endif
96 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
97 
98 enum error_code_t
99 {
100    no_error = 0,
101    system_error,     // system generated error; if possible, is translated
102                      // to one of the more specific errors below.
103    other_error,      // library generated error
104    security_error,   // includes access rights, permissions failures
105    read_only_error,
106    io_error,
107    path_error,
108    not_found_error,
109 //   not_directory_error,
110    busy_error,       // implies trying again might succeed
111    already_exists_error,
112    not_empty_error,
113    is_directory_error,
114    out_of_space_error,
115    out_of_memory_error,
116    out_of_resource_error,
117    lock_error,
118    sem_error,
119    mode_error,
120    size_error,
121    corrupted_error,
122    not_such_file_or_directory,
123    invalid_argument,
124    timeout_when_locking_error,
125    timeout_when_waiting_error,
126    owner_dead_error,
127    not_recoverable
128 };
129 
130 typedef int    native_error_t;
131 
132 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
133 struct ec_xlate
134 {
135    native_error_t sys_ec;
136    error_code_t   ec;
137 };
138 
139 static const ec_xlate ec_table[] =
140 {
141    #if defined (BOOST_INTERPROCESS_WINDOWS)
142    { /*ERROR_ACCESS_DENIED*/5L, security_error },
143    { /*ERROR_INVALID_ACCESS*/12L, security_error },
144    { /*ERROR_SHARING_VIOLATION*/32L, security_error },
145    { /*ERROR_LOCK_VIOLATION*/33L, security_error },
146    { /*ERROR_LOCKED*/212L, security_error },
147    { /*ERROR_NOACCESS*/998L, security_error },
148    { /*ERROR_WRITE_PROTECT*/19L, read_only_error },
149    { /*ERROR_NOT_READY*/21L, io_error },
150    { /*ERROR_SEEK*/25L, io_error },
151    { /*ERROR_READ_FAULT*/30L, io_error },
152    { /*ERROR_WRITE_FAULT*/29L, io_error },
153    { /*ERROR_CANTOPEN*/1011L, io_error },
154    { /*ERROR_CANTREAD*/1012L, io_error },
155    { /*ERROR_CANTWRITE*/1013L, io_error },
156    { /*ERROR_DIRECTORY*/267L, path_error },
157    { /*ERROR_INVALID_NAME*/123L, path_error },
158    { /*ERROR_FILE_NOT_FOUND*/2L, not_found_error },
159    { /*ERROR_PATH_NOT_FOUND*/3L, not_found_error },
160    { /*ERROR_DEV_NOT_EXIST*/55L, not_found_error },
161    { /*ERROR_DEVICE_IN_USE*/2404L, busy_error },
162    { /*ERROR_OPEN_FILES*/2401L, busy_error },
163    { /*ERROR_BUSY_DRIVE*/142L, busy_error },
164    { /*ERROR_BUSY*/170L, busy_error },
165    { /*ERROR_FILE_EXISTS*/80L, already_exists_error },
166    { /*ERROR_ALREADY_EXISTS*/183L, already_exists_error },
167    { /*ERROR_DIR_NOT_EMPTY*/145L, not_empty_error },
168    { /*ERROR_HANDLE_DISK_FULL*/39L, out_of_space_error },
169    { /*ERROR_DISK_FULL*/112L, out_of_space_error },
170    { /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error },
171    { /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error },
172    { /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error },
173    { /*ERROR_INVALID_ADDRESS*/487L, busy_error }
174    #else    //#if defined (BOOST_INTERPROCESS_WINDOWS)
175    { EACCES, security_error },
176    { EROFS, read_only_error },
177    { EIO, io_error },
178    { ENAMETOOLONG, path_error },
179    { ENOENT, not_found_error },
180    //    { ENOTDIR, not_directory_error },
181    { EAGAIN, busy_error },
182    { EBUSY, busy_error },
183    { ETXTBSY, busy_error },
184    { EEXIST, already_exists_error },
185    { ENOTEMPTY, not_empty_error },
186    { EISDIR, is_directory_error },
187    { ENOSPC, out_of_space_error },
188    { ENOMEM, out_of_memory_error },
189    { EMFILE, out_of_resource_error },
190    { ENOENT, not_such_file_or_directory },
191    { EINVAL, invalid_argument }
192    #endif   //#if defined (BOOST_INTERPROCESS_WINDOWS)
193 };
194 
lookup_error(native_error_t err)195 inline error_code_t lookup_error(native_error_t err)
196 {
197    const ec_xlate *cur  = &ec_table[0],
198                   *end  = cur + sizeof(ec_table)/sizeof(ec_xlate);
199    for  (;cur != end; ++cur ){
200       if ( err == cur->sys_ec ) return cur->ec;
201    }
202    return system_error; // general system error code
203 }
204 
205 struct error_info
206 {
error_infoboost::interprocess::error_info207    error_info(error_code_t ec = other_error )
208       :  m_nat(0), m_ec(ec)
209    {}
210 
error_infoboost::interprocess::error_info211    error_info(native_error_t sys_err_code)
212       :  m_nat(sys_err_code), m_ec(lookup_error(sys_err_code))
213    {}
214 
operator =boost::interprocess::error_info215    error_info & operator =(error_code_t ec)
216    {
217       m_nat = 0;
218       m_ec = ec;
219       return *this;
220    }
221 
operator =boost::interprocess::error_info222    error_info & operator =(native_error_t sys_err_code)
223    {
224       m_nat = sys_err_code;
225       m_ec = lookup_error(sys_err_code);
226       return *this;
227    }
228 
get_native_errorboost::interprocess::error_info229    native_error_t get_native_error()const
230    {  return m_nat;  }
231 
get_error_codeboost::interprocess::error_info232    error_code_t   get_error_code()const
233    {  return m_ec;  }
234 
235    private:
236    native_error_t m_nat;
237    error_code_t   m_ec;
238 };
239 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
240 
241 }  // namespace interprocess {
242 }  // namespace boost
243 
244 #include <boost/interprocess/detail/config_end.hpp>
245 
246 #endif // BOOST_INTERPROCESS_ERRORS_HPP
247