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 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 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 };
128
129 typedef int native_error_t;
130
131 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
132 struct ec_xlate
133 {
134 native_error_t sys_ec;
135 error_code_t ec;
136 };
137
138 static const ec_xlate ec_table[] =
139 {
140 #if defined (BOOST_INTERPROCESS_WINDOWS)
141 { /*ERROR_ACCESS_DENIED*/5L, security_error },
142 { /*ERROR_INVALID_ACCESS*/12L, security_error },
143 { /*ERROR_SHARING_VIOLATION*/32L, security_error },
144 { /*ERROR_LOCK_VIOLATION*/33L, security_error },
145 { /*ERROR_LOCKED*/212L, security_error },
146 { /*ERROR_NOACCESS*/998L, security_error },
147 { /*ERROR_WRITE_PROTECT*/19L, read_only_error },
148 { /*ERROR_NOT_READY*/21L, io_error },
149 { /*ERROR_SEEK*/25L, io_error },
150 { /*ERROR_READ_FAULT*/30L, io_error },
151 { /*ERROR_WRITE_FAULT*/29L, io_error },
152 { /*ERROR_CANTOPEN*/1011L, io_error },
153 { /*ERROR_CANTREAD*/1012L, io_error },
154 { /*ERROR_CANTWRITE*/1013L, io_error },
155 { /*ERROR_DIRECTORY*/267L, path_error },
156 { /*ERROR_INVALID_NAME*/123L, path_error },
157 { /*ERROR_FILE_NOT_FOUND*/2L, not_found_error },
158 { /*ERROR_PATH_NOT_FOUND*/3L, not_found_error },
159 { /*ERROR_DEV_NOT_EXIST*/55L, not_found_error },
160 { /*ERROR_DEVICE_IN_USE*/2404L, busy_error },
161 { /*ERROR_OPEN_FILES*/2401L, busy_error },
162 { /*ERROR_BUSY_DRIVE*/142L, busy_error },
163 { /*ERROR_BUSY*/170L, busy_error },
164 { /*ERROR_FILE_EXISTS*/80L, already_exists_error },
165 { /*ERROR_ALREADY_EXISTS*/183L, already_exists_error },
166 { /*ERROR_DIR_NOT_EMPTY*/145L, not_empty_error },
167 { /*ERROR_HANDLE_DISK_FULL*/39L, out_of_space_error },
168 { /*ERROR_DISK_FULL*/112L, out_of_space_error },
169 { /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error },
170 { /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error },
171 { /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error },
172 { /*ERROR_INVALID_ADDRESS*/487L, busy_error }
173 #else //#if defined (BOOST_INTERPROCESS_WINDOWS)
174 { EACCES, security_error },
175 { EROFS, read_only_error },
176 { EIO, io_error },
177 { ENAMETOOLONG, path_error },
178 { ENOENT, not_found_error },
179 // { ENOTDIR, not_directory_error },
180 { EAGAIN, busy_error },
181 { EBUSY, busy_error },
182 { ETXTBSY, busy_error },
183 { EEXIST, already_exists_error },
184 { ENOTEMPTY, not_empty_error },
185 { EISDIR, is_directory_error },
186 { ENOSPC, out_of_space_error },
187 { ENOMEM, out_of_memory_error },
188 { EMFILE, out_of_resource_error },
189 { ENOENT, not_such_file_or_directory },
190 { EINVAL, invalid_argument }
191 #endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
192 };
193
lookup_error(native_error_t err)194 inline error_code_t lookup_error(native_error_t err)
195 {
196 const ec_xlate *cur = &ec_table[0],
197 *end = cur + sizeof(ec_table)/sizeof(ec_xlate);
198 for (;cur != end; ++cur ){
199 if ( err == cur->sys_ec ) return cur->ec;
200 }
201 return system_error; // general system error code
202 }
203
204 struct error_info
205 {
error_infoboost::interprocess::error_info206 error_info(error_code_t ec = other_error )
207 : m_nat(0), m_ec(ec)
208 {}
209
error_infoboost::interprocess::error_info210 error_info(native_error_t sys_err_code)
211 : m_nat(sys_err_code), m_ec(lookup_error(sys_err_code))
212 {}
213
operator =boost::interprocess::error_info214 error_info & operator =(error_code_t ec)
215 {
216 m_nat = 0;
217 m_ec = ec;
218 return *this;
219 }
220
operator =boost::interprocess::error_info221 error_info & operator =(native_error_t sys_err_code)
222 {
223 m_nat = sys_err_code;
224 m_ec = lookup_error(sys_err_code);
225 return *this;
226 }
227
get_native_errorboost::interprocess::error_info228 native_error_t get_native_error()const
229 { return m_nat; }
230
get_error_codeboost::interprocess::error_info231 error_code_t get_error_code()const
232 { return m_ec; }
233
234 private:
235 native_error_t m_nat;
236 error_code_t m_ec;
237 };
238 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
239
240 } // namespace interprocess {
241 } // namespace boost
242
243 #include <boost/interprocess/detail/config_end.hpp>
244
245 #endif // BOOST_INTERPROCESS_ERRORS_HPP
246