1 /*
2  * BoostErrors.cpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 #include <core/BoostErrors.hpp>
17 
18 #include <core/BoostThread.hpp>
19 
20 // we define BOOST_USE_WINDOWS_H on mingw64 to work around some
21 // incompatabilities. however, this prevents the interprocess headers
22 // from compiling so we undef it in this localized context
23 #if defined(__GNUC__) && defined(_WIN64)
24    #undef BOOST_USE_WINDOWS_H
25 #endif
26 
27 #include <boost/interprocess/errors.hpp>
28 #include <boost/interprocess/exceptions.hpp>
29 
30 using namespace boost::system;
31 
32 namespace RSTUDIO_BOOST_NAMESPACE {
33 namespace interprocess {
34 
35 class interprocess_error_category : public error_category
36 {
37 public:
38    const char* name() const BOOST_NOEXCEPT;
39    std::string message(int ev) const;
40 };
41 
interprocess_category()42 const error_category& interprocess_category()
43 {
44    static interprocess_error_category interprocessCategoryConst;
45    return interprocessCategoryConst;
46 }
47 
name() const48 const char* interprocess_error_category::name() const BOOST_NOEXCEPT
49 {
50    return "interprocess";
51 }
52 
message(int ev) const53 std::string interprocess_error_category::message(int ev) const
54 {
55    std::string message;
56    switch (ev)
57    {
58       case no_error:
59          message = "No error";
60          break;
61 
62       case system_error:
63          message = "System error";
64          break;
65 
66       case other_error:
67          message = "Library generated error";
68          break;
69 
70       case security_error:
71          message = "Security error";
72          break;
73 
74       case read_only_error:
75          message = "Read only error";
76          break;
77 
78       case io_error:
79          message = "IO error";
80          break;
81 
82       case path_error:
83          message = "Path error";
84          break;
85 
86       case not_found_error:
87          message = "Not found error";
88          break;
89 
90       case busy_error:
91          message = "Busy error";
92          break;
93 
94       case already_exists_error:
95          message = "Already exists error";
96          break;
97 
98       case not_empty_error:
99          message = "Not empty error";
100          break;
101 
102       case is_directory_error:
103          message = "Is directory error";
104          break;
105 
106       case out_of_space_error:
107          message = "Out of space error";
108          break;
109 
110       case out_of_memory_error:
111          message = "Out of memory error";
112          break;
113 
114       case out_of_resource_error:
115          message = "Out of resource error";
116          break;
117 
118       case lock_error:
119          message = "Lock error";
120          break;
121 
122       case sem_error:
123          message = "Sem error";
124          break;
125 
126       case mode_error:
127          message = "Mode error";
128          break;
129 
130       case size_error:
131          message = "Size error";
132          break;
133 
134       case corrupted_error:
135          message = "Corrupted error";
136          break;
137 
138       default:
139          message = "Unknown error";
140          break;
141    }
142 
143    return message;
144 }
145 
146 
147 
ec_from_exception(const interprocess_exception & e)148 boost::system::error_code ec_from_exception(const interprocess_exception& e)
149 {
150    if (e.get_error_code() == system_error)
151       return error_code(e.get_native_error(), system_category());
152    else
153       return error_code(e.get_error_code(), interprocess_category());
154 }
155 
156 } // namespace interprocess
157 
158 
159 // thread_error
160 namespace thread_error {
161 
162 namespace errc {
163 enum errc_t {
164    thread_resource_error = 1
165 };
166 } // namespace thread_errc
167 
168 
169 class thread_error_category : public error_category
170 {
171 public:
172    const char* name() const BOOST_NOEXCEPT;
173    std::string message(int ev) const;
174 };
175 
thread_category()176 const error_category& thread_category()
177 {
178    static thread_error_category threadCategoryConst;
179    return threadCategoryConst;
180 }
181 
name() const182 const char* thread_error_category::name() const BOOST_NOEXCEPT
183 {
184    return "thread";
185 }
186 
message(int ev) const187 std::string thread_error_category::message(int ev) const
188 {
189    std::string message;
190    switch (ev)
191    {
192       // only one error code for now
193       case errc::thread_resource_error:
194       default:
195          message = "Thread resource error";
196          break;
197    }
198    return message;
199 }
200 
ec_from_exception(const boost::thread_resource_error & e)201 boost::system::error_code ec_from_exception(
202       const boost::thread_resource_error& e)
203 {
204    return error_code(errc::thread_resource_error, thread_category());
205 }
206 
207 } // namespace thread_error
208 
209 } // namespace boost
210 
211 
212 
213 
214