1 // <system_error> implementation file
2
3 // Copyright (C) 2007-2022 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25
26 #define _GLIBCXX_USE_CXX11_ABI 1
27 #define __sso_string __sso_stringxxx
28 #include <cstring>
29 #include <system_error>
30 #include <bits/functexcept.h>
31 #include <limits>
32 #include <errno.h>
33 #undef __sso_string
34
35 #if defined(_WIN32) && !defined(__CYGWIN__)
36 #include <memory>
37 #include <windows.h>
38 #endif
39
40 #if __has_cpp_attribute(clang::require_constant_initialization)
41 # define __constinit [[clang::require_constant_initialization]]
42 #endif
43
44 namespace
45 {
46 using std::string;
47
48 template<typename T>
49 struct constant_init
50 {
51 union {
52 unsigned char unused;
53 T obj;
54 };
constant_init__anon75eab2510111::constant_init55 constexpr constant_init() : obj() { }
56
~constant_init__anon75eab2510111::constant_init57 ~constant_init() { /* do nothing, union member is not destroyed */ }
58 };
59
60 struct generic_error_category final : public std::error_category
61 {
62 const char*
name__anon75eab2510111::generic_error_category63 name() const noexcept final
64 { return "generic"; }
65
66 _GLIBCXX_DEFAULT_ABI_TAG
67 string
message__anon75eab2510111::generic_error_category68 message(int i) const final
69 {
70 // XXX locale issues: how does one get or set loc.
71 // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
72 return string(strerror(i));
73 }
74
75 // Override this to avoid a virtual call to default_error_condition(i).
76 bool
equivalent__anon75eab2510111::generic_error_category77 equivalent(int i, const std::error_condition& cond) const noexcept final
78 { return i == cond.value() && *this == cond.category(); }
79 };
80
81 __constinit constant_init<generic_error_category> generic_category_instance{};
82
83 struct system_error_category final : public std::error_category
84 {
85 const char*
name__anon75eab2510111::system_error_category86 name() const noexcept final
87 { return "system"; }
88
89 _GLIBCXX_DEFAULT_ABI_TAG
90 string
message__anon75eab2510111::system_error_category91 message(int i) const final
92 {
93 #if defined(_WIN32) && !defined(__CYGWIN__)
94 char* buf = nullptr;
95 auto len
96 = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
97 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
98 nullptr,
99 i,
100 LANG_USER_DEFAULT,
101 reinterpret_cast<LPTSTR>(&buf),
102 0,
103 nullptr);
104 if (len > 0)
105 {
106 struct deleter {
107 void operator()(void* p) const { ::LocalFree(p); }
108 };
109 std::unique_ptr<char[], deleter> guard(buf);
110 if (len > 3 && !__builtin_memcmp(buf + len - 3, ".\r\n", 3)) [[likely]]
111 len -= 3;
112 return string(buf, len);
113 }
114 return string("Unknown error code");
115 #else
116 // XXX locale issues: how does one get or set loc.
117 // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
118 return string(strerror(i));
119 #endif
120 }
121
122 std::error_condition
default_error_condition__anon75eab2510111::system_error_category123 default_error_condition(int ev) const noexcept final
124 {
125 // Use generic category for all known POSIX errno values (including zero)
126 // and system category otherwise.
127 switch (ev)
128 {
129 #if defined(_WIN32) && !defined(__CYGWIN__)
130 case 0:
131 return {0, generic_category_instance.obj};
132 // Convert Windows error code into a corresponding POSIX errno value.
133 #define X(w, e) case ERROR_##w: return {e, generic_category_instance.obj};
134 // This list is based on Cygwin's winsup/cygwin/errno.cc
135 X (ACCESS_DENIED, EACCES);
136 X (ACTIVE_CONNECTIONS, EAGAIN);
137 X (ALREADY_EXISTS, EEXIST);
138 X (BAD_DEVICE, ENODEV);
139 X (BAD_EXE_FORMAT, ENOEXEC);
140 X (BAD_NETPATH, ENOENT);
141 X (BAD_NET_NAME, ENOENT);
142 X (BAD_NET_RESP, ENOSYS);
143 X (BAD_PATHNAME, ENOENT);
144 X (BAD_PIPE, EINVAL);
145 X (BAD_UNIT, ENODEV);
146 X (BAD_USERNAME, EINVAL);
147 X (BEGINNING_OF_MEDIA, EIO);
148 X (BROKEN_PIPE, EPIPE);
149 X (BUSY, EBUSY);
150 X (BUS_RESET, EIO);
151 X (CALL_NOT_IMPLEMENTED, ENOSYS);
152 X (CANCELLED, EINTR);
153 X (CANNOT_MAKE, EPERM);
154 X (CHILD_NOT_COMPLETE, EBUSY);
155 X (COMMITMENT_LIMIT, EAGAIN);
156 X (CONNECTION_REFUSED, ECONNREFUSED);
157 X (CRC, EIO);
158 X (DEVICE_DOOR_OPEN, EIO);
159 X (DEVICE_IN_USE, EAGAIN);
160 X (DEVICE_REQUIRES_CLEANING, EIO);
161 X (DEV_NOT_EXIST, ENOENT);
162 X (DIRECTORY, ENOTDIR);
163 X (DIR_NOT_EMPTY, ENOTEMPTY);
164 X (DISK_CORRUPT, EIO);
165 #ifdef ENOSPC
166 X (DISK_FULL, ENOSPC);
167 #endif
168 X (DS_GENERIC_ERROR, EIO);
169 #ifdef ENOSPC
170 X (END_OF_MEDIA, ENOSPC);
171 #endif
172 X (EOM_OVERFLOW, EIO);
173 X (EXE_MACHINE_TYPE_MISMATCH, ENOEXEC);
174 X (EXE_MARKED_INVALID, ENOEXEC);
175 X (FILEMARK_DETECTED, EIO);
176 X (FILENAME_EXCED_RANGE, ENAMETOOLONG);
177 X (FILE_CORRUPT, EEXIST);
178 X (FILE_EXISTS, EEXIST);
179 X (FILE_INVALID, ENXIO);
180 X (FILE_NOT_FOUND, ENOENT);
181 #ifdef ENOSPC
182 X (HANDLE_DISK_FULL, ENOSPC);
183 #endif
184 X (INVALID_ADDRESS, EINVAL);
185 X (INVALID_AT_INTERRUPT_TIME, EINTR);
186 X (INVALID_BLOCK_LENGTH, EIO);
187 X (INVALID_DATA, EINVAL);
188 X (INVALID_DRIVE, ENODEV);
189 X (INVALID_EA_NAME, EINVAL);
190 X (INVALID_EXE_SIGNATURE, ENOEXEC);
191 X (INVALID_HANDLE, EBADF);
192 X (INVALID_NAME, ENOENT);
193 X (INVALID_PARAMETER, EINVAL);
194 X (INVALID_SIGNAL_NUMBER, EINVAL);
195 X (IOPL_NOT_ENABLED, ENOEXEC);
196 X (IO_DEVICE, EIO);
197 X (IO_INCOMPLETE, EAGAIN);
198 X (IO_PENDING, EAGAIN);
199 X (LOCK_VIOLATION, EBUSY);
200 X (MAX_THRDS_REACHED, EAGAIN);
201 X (META_EXPANSION_TOO_LONG, EINVAL);
202 X (MOD_NOT_FOUND, ENOENT);
203 X (MORE_DATA, EMSGSIZE);
204 X (NEGATIVE_SEEK, EINVAL);
205 X (NETNAME_DELETED, ENOENT);
206 X (NOACCESS, EFAULT);
207 X (NONE_MAPPED, EINVAL);
208 X (NONPAGED_SYSTEM_RESOURCES, EAGAIN);
209 X (NOT_ENOUGH_MEMORY, ENOMEM);
210 X (NOT_ENOUGH_QUOTA, EIO);
211 #ifdef EPERM
212 X (NOT_OWNER, EPERM);
213 #else
214 X (NOT_OWNER, EACCES);
215 #endif
216 X (NOT_SAME_DEVICE, EXDEV);
217 X (NOT_SUPPORTED, ENOSYS);
218 X (NO_DATA, EPIPE);
219 X (NO_DATA_DETECTED, EIO);
220 X (NO_MORE_SEARCH_HANDLES, ENFILE);
221 X (NO_PROC_SLOTS, EAGAIN);
222 X (NO_SIGNAL_SENT, EIO);
223 X (NO_SYSTEM_RESOURCES, EFBIG);
224 X (NO_TOKEN, EINVAL);
225 X (OPEN_FAILED, EIO);
226 X (OPEN_FILES, EAGAIN);
227 X (OUTOFMEMORY, ENOMEM);
228 X (PAGED_SYSTEM_RESOURCES, EAGAIN);
229 X (PAGEFILE_QUOTA, EAGAIN);
230 X (PATH_NOT_FOUND, ENOENT);
231 X (PIPE_BUSY, EBUSY);
232 X (PIPE_CONNECTED, EBUSY);
233 X (POSSIBLE_DEADLOCK, EDEADLK);
234 X (PRIVILEGE_NOT_HELD, EPERM);
235 X (PROCESS_ABORTED, EFAULT);
236 X (PROC_NOT_FOUND, ESRCH);
237 X (SECTOR_NOT_FOUND, EINVAL);
238 X (SEEK, EINVAL);
239 X (SERVICE_REQUEST_TIMEOUT, EBUSY);
240 X (SETMARK_DETECTED, EIO);
241 X (SHARING_BUFFER_EXCEEDED, ENOLCK);
242 X (SHARING_VIOLATION, EBUSY);
243 X (SIGNAL_PENDING, EBUSY);
244 X (SIGNAL_REFUSED, EIO);
245 X (THREAD_1_INACTIVE, EINVAL);
246 X (TIMEOUT, EBUSY);
247 X (TOO_MANY_LINKS, EMLINK);
248 X (TOO_MANY_OPEN_FILES, EMFILE);
249 X (UNEXP_NET_ERR, EIO);
250 X (WORKING_SET_QUOTA, EAGAIN);
251 X (WRITE_PROTECT, EROFS);
252 #undef X
253
254 #elif defined __AVR__
255 // avr-libc only defines a few distinct error numbers. Most <errno.h>
256 // constants are not usable in #if directives and have the same value.
257 case EDOM:
258 case ERANGE:
259 case ENOSYS:
260 case EINTR:
261 case 0:
262 return std::error_condition(ev, generic_category_instance.obj);
263 #else
264 // List of errno macros from [cerrno.syn].
265 // C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX.
266 // They expand to integer constant expressions with type int,
267 // and distinct positive values, suitable for use in #if directives.
268 // POSIX adds more macros (but they're not defined on all targets,
269 // see config/os/.../error_constants.h), and POSIX allows
270 // EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP.
271
272 #ifdef E2BIG
273 case E2BIG:
274 #endif
275 #ifdef EACCES
276 case EACCES:
277 #endif
278 #ifdef EADDRINUSE
279 case EADDRINUSE:
280 #endif
281 #ifdef EADDRNOTAVAIL
282 case EADDRNOTAVAIL:
283 #endif
284 #ifdef EAFNOSUPPORT
285 case EAFNOSUPPORT:
286 #endif
287 #ifdef EAGAIN
288 case EAGAIN:
289 #endif
290 #ifdef EALREADY
291 case EALREADY:
292 #endif
293 #ifdef EBADF
294 case EBADF:
295 #endif
296 #ifdef EBADMSG
297 case EBADMSG:
298 #endif
299 #ifdef EBUSY
300 case EBUSY:
301 #endif
302 #ifdef ECANCELED
303 case ECANCELED:
304 #endif
305 #ifdef ECHILD
306 case ECHILD:
307 #endif
308 #ifdef ECONNABORTED
309 case ECONNABORTED:
310 #endif
311 #ifdef ECONNREFUSED
312 case ECONNREFUSED:
313 #endif
314 #ifdef ECONNRESET
315 case ECONNRESET:
316 #endif
317 #ifdef EDEADLK
318 case EDEADLK:
319 #endif
320 #ifdef EDESTADDRREQ
321 case EDESTADDRREQ:
322 #endif
323 case EDOM:
324 #ifdef EEXIST
325 case EEXIST:
326 #endif
327 #ifdef EFAULT
328 case EFAULT:
329 #endif
330 #ifdef EFBIG
331 case EFBIG:
332 #endif
333 #ifdef EHOSTUNREACH
334 case EHOSTUNREACH:
335 #endif
336 #ifdef EIDRM
337 case EIDRM:
338 #endif
339 case EILSEQ:
340 #ifdef EINPROGRESS
341 case EINPROGRESS:
342 #endif
343 #ifdef EINTR
344 case EINTR:
345 #endif
346 #ifdef EINVAL
347 case EINVAL:
348 #endif
349 #ifdef EIO
350 case EIO:
351 #endif
352 #ifdef EISCONN
353 case EISCONN:
354 #endif
355 #ifdef EISDIR
356 case EISDIR:
357 #endif
358 #ifdef ELOOP
359 case ELOOP:
360 #endif
361 #ifdef EMFILE
362 case EMFILE:
363 #endif
364 #ifdef EMLINK
365 case EMLINK:
366 #endif
367 #ifdef EMSGSIZE
368 case EMSGSIZE:
369 #endif
370 #ifdef ENAMETOOLONG
371 case ENAMETOOLONG:
372 #endif
373 #ifdef ENETDOWN
374 case ENETDOWN:
375 #endif
376 #ifdef ENETRESET
377 case ENETRESET:
378 #endif
379 #ifdef ENETUNREACH
380 case ENETUNREACH:
381 #endif
382 #ifdef ENFILE
383 case ENFILE:
384 #endif
385 #ifdef ENOBUFS
386 case ENOBUFS:
387 #endif
388 #ifdef ENODATA
389 case ENODATA:
390 #endif
391 #ifdef ENODEV
392 case ENODEV:
393 #endif
394 #ifdef ENOENT
395 case ENOENT:
396 #endif
397 #ifdef ENOEXEC
398 case ENOEXEC:
399 #endif
400 #ifdef ENOLCK
401 case ENOLCK:
402 #endif
403 #ifdef ENOLINK
404 case ENOLINK:
405 #endif
406 #ifdef ENOMEM
407 case ENOMEM:
408 #endif
409 #ifdef ENOMSG
410 case ENOMSG:
411 #endif
412 #ifdef ENOPROTOOPT
413 case ENOPROTOOPT:
414 #endif
415 #ifdef ENOSPC
416 case ENOSPC:
417 #endif
418 #ifdef ENOSR
419 case ENOSR:
420 #endif
421 #ifdef ENOSTR
422 case ENOSTR:
423 #endif
424 #ifdef ENOSYS
425 case ENOSYS:
426 #endif
427 #ifdef ENOTCONN
428 case ENOTCONN:
429 #endif
430 #ifdef ENOTDIR
431 case ENOTDIR:
432 #endif
433 #if defined ENOTEMPTY && (!defined EEXIST || ENOTEMPTY != EEXIST)
434 // AIX sometimes uses the same value for EEXIST and ENOTEMPTY
435 case ENOTEMPTY:
436 #endif
437 #ifdef ENOTRECOVERABLE
438 case ENOTRECOVERABLE:
439 #endif
440 #ifdef ENOTSOCK
441 case ENOTSOCK:
442 #endif
443 #if defined ENOTSUP && (!defined ENOSYS || ENOTSUP != ENOSYS)
444 // zTPF uses the same value for ENOSYS and ENOTSUP
445 case ENOTSUP:
446 #endif
447 #ifdef ENOTTY
448 case ENOTTY:
449 #endif
450 #ifdef ENXIO
451 case ENXIO:
452 #endif
453 #if defined EOPNOTSUPP && (!defined ENOTSUP || EOPNOTSUPP != ENOTSUP)
454 case EOPNOTSUPP:
455 #endif
456 #ifdef EOVERFLOW
457 case EOVERFLOW:
458 #endif
459 #ifdef EOWNERDEAD
460 case EOWNERDEAD:
461 #endif
462 #ifdef EPERM
463 case EPERM:
464 #endif
465 #ifdef EPIPE
466 case EPIPE:
467 #endif
468 #ifdef EPROTO
469 case EPROTO:
470 #endif
471 #ifdef EPROTONOSUPPORT
472 case EPROTONOSUPPORT:
473 #endif
474 #ifdef EPROTOTYPE
475 case EPROTOTYPE:
476 #endif
477 case ERANGE:
478 #ifdef EROFS
479 case EROFS:
480 #endif
481 #ifdef ESPIPE
482 case ESPIPE:
483 #endif
484 #ifdef ESRCH
485 case ESRCH:
486 #endif
487 #ifdef ETIME
488 case ETIME:
489 #endif
490 #ifdef ETIMEDOUT
491 case ETIMEDOUT:
492 #endif
493 #ifdef ETXTBSY
494 case ETXTBSY:
495 #endif
496 #if defined EWOULDBLOCK && (!defined EAGAIN || EWOULDBLOCK != EAGAIN)
497 case EWOULDBLOCK:
498 #endif
499 #ifdef EXDEV
500 case EXDEV:
501 #endif
502 case 0:
503 return std::error_condition(ev, generic_category_instance.obj);
504
505 /* Additional system-dependent mappings from non-standard error codes
506 * to one of the POSIX values above would go here, e.g.
507 case EBLAH:
508 return std::error_condition(EINVAL, std::generic_category());
509 */
510
511 #endif
512 default:
513 return std::error_condition(ev, *this);
514 }
515 }
516
517 // Override this to avoid a virtual call to default_error_condition(i).
518 bool
equivalent__anon75eab2510111::system_error_category519 equivalent(int i, const std::error_condition& cond) const noexcept final
520 { return system_error_category::default_error_condition(i) == cond; }
521 };
522
523 __constinit constant_init<system_error_category> system_category_instance{};
524 }
525
526 namespace std _GLIBCXX_VISIBILITY(default)
527 {
528 _GLIBCXX_BEGIN_NAMESPACE_VERSION
529
530 void
__throw_system_error(int __i)531 __throw_system_error(int __i __attribute__((unused)))
532 {
533 _GLIBCXX_THROW_OR_ABORT(system_error(__i, generic_category_instance.obj));
534 }
535
536 error_category::~error_category() = default;
537
_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) const538 _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
539
540 const error_category&
541 system_category() noexcept { return system_category_instance.obj; }
542
543 const error_category&
generic_category()544 generic_category() noexcept { return generic_category_instance.obj; }
545
546 _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
547
548 system_error::~system_error() = default;
549
550 error_condition
default_error_condition(int __i) const551 error_category::default_error_condition(int __i) const noexcept
552 { return error_condition(__i, *this); }
553
554 bool
equivalent(int __i,const error_condition & __cond) const555 error_category::equivalent(int __i,
556 const error_condition& __cond) const noexcept
557 { return default_error_condition(__i) == __cond; }
558
559 bool
equivalent(const error_code & __code,int __i) const560 error_category::equivalent(const error_code& __code, int __i) const noexcept
561 { return *this == __code.category() && __code.value() == __i; }
562
563 error_condition
default_error_condition() const564 error_code::default_error_condition() const noexcept
565 { return category().default_error_condition(value()); }
566
567 #if _GLIBCXX_USE_CXX11_ABI
568 // Return error_category::message() as a COW string
569 __cow_string
_M_message(int i) const570 error_category::_M_message(int i) const
571 {
572 string msg = this->message(i);
573 return {msg.c_str(), msg.length()};
574 }
575 #endif
576
577 _GLIBCXX_END_NAMESPACE_VERSION
578 } // namespace
579