]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
7c673cae FG |
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 | |
20effc67 | 43 | # include <cerrno> //Errors |
7c673cae FG |
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) | |
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) | |
67 | inline void fill_system_message(int sys_err_code, std::string &str) | |
68 | { | |
69 | void *lpMsgBuf; | |
92f5a8d4 | 70 | unsigned long ret = winapi::format_message( |
7c673cae FG |
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 | ); | |
92f5a8d4 TL |
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 | } | |
7c673cae FG |
91 | } |
92 | # else | |
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 | ||
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 | { | |
206 | error_info(error_code_t ec = other_error ) | |
207 | : m_nat(0), m_ec(ec) | |
208 | {} | |
209 | ||
210 | error_info(native_error_t sys_err_code) | |
211 | : m_nat(sys_err_code), m_ec(lookup_error(sys_err_code)) | |
212 | {} | |
213 | ||
214 | error_info & operator =(error_code_t ec) | |
215 | { | |
216 | m_nat = 0; | |
217 | m_ec = ec; | |
218 | return *this; | |
219 | } | |
220 | ||
221 | 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 | ||
228 | native_error_t get_native_error()const | |
229 | { return m_nat; } | |
230 | ||
231 | 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 |