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