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