]>
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> | |
37 | #include <stdarg.h> | |
38 | #include <string> | |
39 | ||
40 | #if defined (BOOST_INTERPROCESS_WINDOWS) | |
41 | # include <boost/interprocess/detail/win32_api.hpp> | |
42 | #else | |
43 | # ifdef BOOST_HAS_UNISTD_H | |
44 | # include <errno.h> //Errors | |
45 | # include <cstring> //strerror | |
46 | # else //ifdef BOOST_HAS_UNISTD_H | |
47 | # error Unknown platform | |
48 | # endif //ifdef BOOST_HAS_UNISTD_H | |
49 | #endif //#if defined (BOOST_INTERPROCESS_WINDOWS) | |
50 | ||
51 | //!\file | |
52 | //!Describes the error numbering of interprocess classes | |
53 | ||
54 | namespace boost { | |
55 | namespace interprocess { | |
56 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) | |
57 | inline int system_error_code() // artifact of POSIX and WINDOWS error reporting | |
58 | { | |
59 | #if defined (BOOST_INTERPROCESS_WINDOWS) | |
60 | return winapi::get_last_error(); | |
61 | #else | |
62 | return errno; // GCC 3.1 won't accept ::errno | |
63 | #endif | |
64 | } | |
65 | ||
66 | ||
67 | #if defined (BOOST_INTERPROCESS_WINDOWS) | |
68 | inline void fill_system_message(int sys_err_code, std::string &str) | |
69 | { | |
70 | void *lpMsgBuf; | |
71 | winapi::format_message( | |
72 | winapi::format_message_allocate_buffer | | |
73 | winapi::format_message_from_system | | |
74 | winapi::format_message_ignore_inserts, | |
75 | 0, | |
76 | sys_err_code, | |
77 | winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language | |
78 | reinterpret_cast<char *>(&lpMsgBuf), | |
79 | 0, | |
80 | 0 | |
81 | ); | |
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 | inline void fill_system_message( int system_error, std::string &str) | |
90 | { str = std::strerror(system_error); } | |
91 | # endif | |
92 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED | |
93 | ||
94 | enum error_code_t | |
95 | { | |
96 | no_error = 0, | |
97 | system_error, // system generated error; if possible, is translated | |
98 | // to one of the more specific errors below. | |
99 | other_error, // library generated error | |
100 | security_error, // includes access rights, permissions failures | |
101 | read_only_error, | |
102 | io_error, | |
103 | path_error, | |
104 | not_found_error, | |
105 | // not_directory_error, | |
106 | busy_error, // implies trying again might succeed | |
107 | already_exists_error, | |
108 | not_empty_error, | |
109 | is_directory_error, | |
110 | out_of_space_error, | |
111 | out_of_memory_error, | |
112 | out_of_resource_error, | |
113 | lock_error, | |
114 | sem_error, | |
115 | mode_error, | |
116 | size_error, | |
117 | corrupted_error, | |
118 | not_such_file_or_directory, | |
119 | invalid_argument, | |
120 | timeout_when_locking_error, | |
121 | timeout_when_waiting_error, | |
122 | owner_dead_error | |
123 | }; | |
124 | ||
125 | typedef int native_error_t; | |
126 | ||
127 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) | |
128 | struct ec_xlate | |
129 | { | |
130 | native_error_t sys_ec; | |
131 | error_code_t ec; | |
132 | }; | |
133 | ||
134 | static const ec_xlate ec_table[] = | |
135 | { | |
136 | #if defined (BOOST_INTERPROCESS_WINDOWS) | |
137 | { /*ERROR_ACCESS_DENIED*/5L, security_error }, | |
138 | { /*ERROR_INVALID_ACCESS*/12L, security_error }, | |
139 | { /*ERROR_SHARING_VIOLATION*/32L, security_error }, | |
140 | { /*ERROR_LOCK_VIOLATION*/33L, security_error }, | |
141 | { /*ERROR_LOCKED*/212L, security_error }, | |
142 | { /*ERROR_NOACCESS*/998L, security_error }, | |
143 | { /*ERROR_WRITE_PROTECT*/19L, read_only_error }, | |
144 | { /*ERROR_NOT_READY*/21L, io_error }, | |
145 | { /*ERROR_SEEK*/25L, io_error }, | |
146 | { /*ERROR_READ_FAULT*/30L, io_error }, | |
147 | { /*ERROR_WRITE_FAULT*/29L, io_error }, | |
148 | { /*ERROR_CANTOPEN*/1011L, io_error }, | |
149 | { /*ERROR_CANTREAD*/1012L, io_error }, | |
150 | { /*ERROR_CANTWRITE*/1013L, io_error }, | |
151 | { /*ERROR_DIRECTORY*/267L, path_error }, | |
152 | { /*ERROR_INVALID_NAME*/123L, path_error }, | |
153 | { /*ERROR_FILE_NOT_FOUND*/2L, not_found_error }, | |
154 | { /*ERROR_PATH_NOT_FOUND*/3L, not_found_error }, | |
155 | { /*ERROR_DEV_NOT_EXIST*/55L, not_found_error }, | |
156 | { /*ERROR_DEVICE_IN_USE*/2404L, busy_error }, | |
157 | { /*ERROR_OPEN_FILES*/2401L, busy_error }, | |
158 | { /*ERROR_BUSY_DRIVE*/142L, busy_error }, | |
159 | { /*ERROR_BUSY*/170L, busy_error }, | |
160 | { /*ERROR_FILE_EXISTS*/80L, already_exists_error }, | |
161 | { /*ERROR_ALREADY_EXISTS*/183L, already_exists_error }, | |
162 | { /*ERROR_DIR_NOT_EMPTY*/145L, not_empty_error }, | |
163 | { /*ERROR_HANDLE_DISK_FULL*/39L, out_of_space_error }, | |
164 | { /*ERROR_DISK_FULL*/112L, out_of_space_error }, | |
165 | { /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error }, | |
166 | { /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error }, | |
167 | { /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error }, | |
168 | { /*ERROR_INVALID_ADDRESS*/487L, busy_error } | |
169 | #else //#if defined (BOOST_INTERPROCESS_WINDOWS) | |
170 | { EACCES, security_error }, | |
171 | { EROFS, read_only_error }, | |
172 | { EIO, io_error }, | |
173 | { ENAMETOOLONG, path_error }, | |
174 | { ENOENT, not_found_error }, | |
175 | // { ENOTDIR, not_directory_error }, | |
176 | { EAGAIN, busy_error }, | |
177 | { EBUSY, busy_error }, | |
178 | { ETXTBSY, busy_error }, | |
179 | { EEXIST, already_exists_error }, | |
180 | { ENOTEMPTY, not_empty_error }, | |
181 | { EISDIR, is_directory_error }, | |
182 | { ENOSPC, out_of_space_error }, | |
183 | { ENOMEM, out_of_memory_error }, | |
184 | { EMFILE, out_of_resource_error }, | |
185 | { ENOENT, not_such_file_or_directory }, | |
186 | { EINVAL, invalid_argument } | |
187 | #endif //#if defined (BOOST_INTERPROCESS_WINDOWS) | |
188 | }; | |
189 | ||
190 | inline error_code_t lookup_error(native_error_t err) | |
191 | { | |
192 | const ec_xlate *cur = &ec_table[0], | |
193 | *end = cur + sizeof(ec_table)/sizeof(ec_xlate); | |
194 | for (;cur != end; ++cur ){ | |
195 | if ( err == cur->sys_ec ) return cur->ec; | |
196 | } | |
197 | return system_error; // general system error code | |
198 | } | |
199 | ||
200 | struct error_info | |
201 | { | |
202 | error_info(error_code_t ec = other_error ) | |
203 | : m_nat(0), m_ec(ec) | |
204 | {} | |
205 | ||
206 | error_info(native_error_t sys_err_code) | |
207 | : m_nat(sys_err_code), m_ec(lookup_error(sys_err_code)) | |
208 | {} | |
209 | ||
210 | error_info & operator =(error_code_t ec) | |
211 | { | |
212 | m_nat = 0; | |
213 | m_ec = ec; | |
214 | return *this; | |
215 | } | |
216 | ||
217 | error_info & operator =(native_error_t sys_err_code) | |
218 | { | |
219 | m_nat = sys_err_code; | |
220 | m_ec = lookup_error(sys_err_code); | |
221 | return *this; | |
222 | } | |
223 | ||
224 | native_error_t get_native_error()const | |
225 | { return m_nat; } | |
226 | ||
227 | error_code_t get_error_code()const | |
228 | { return m_ec; } | |
229 | ||
230 | private: | |
231 | native_error_t m_nat; | |
232 | error_code_t m_ec; | |
233 | }; | |
234 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED | |
235 | ||
236 | } // namespace interprocess { | |
237 | } // namespace boost | |
238 | ||
239 | #include <boost/interprocess/detail/config_end.hpp> | |
240 | ||
241 | #endif // BOOST_INTERPROCESS_ERRORS_HPP |