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__anon0ba1c7a70111::constant_init55       constexpr constant_init() : obj() { }
56 
~constant_init__anon0ba1c7a70111::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__anon0ba1c7a70111::generic_error_category63     name() const noexcept final
64     { return "generic"; }
65 
66     _GLIBCXX_DEFAULT_ABI_TAG
67     string
message__anon0ba1c7a70111::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__anon0ba1c7a70111::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__anon0ba1c7a70111::system_error_category86     name() const noexcept final
87     { return "system"; }
88 
89     _GLIBCXX_DEFAULT_ABI_TAG
90     string
message__anon0ba1c7a70111::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__anon0ba1c7a70111::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__anon0ba1c7a70111::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 
538   const error_category&
system_category()539   _V2::system_category() noexcept { return system_category_instance.obj; }
540 
541   const error_category&
generic_category()542   _V2::generic_category() noexcept { return generic_category_instance.obj; }
543 
544   system_error::~system_error() = default;
545 
546   error_condition
default_error_condition(int __i) const547   error_category::default_error_condition(int __i) const noexcept
548   { return error_condition(__i, *this); }
549 
550   bool
equivalent(int __i,const error_condition & __cond) const551   error_category::equivalent(int __i,
552 			     const error_condition& __cond) const noexcept
553   { return default_error_condition(__i) == __cond; }
554 
555   bool
equivalent(const error_code & __code,int __i) const556   error_category::equivalent(const error_code& __code, int __i) const noexcept
557   { return *this == __code.category() && __code.value() == __i; }
558 
559   error_condition
default_error_condition() const560   error_code::default_error_condition() const noexcept
561   { return category().default_error_condition(value()); }
562 
563 #if _GLIBCXX_USE_CXX11_ABI
564   // Return error_category::message() as a COW string
565   __cow_string
_M_message(int i) const566   error_category::_M_message(int i) const
567   {
568     string msg = this->message(i);
569     return {msg.c_str(), msg.length()};
570   }
571 #endif
572 
573 _GLIBCXX_END_NAMESPACE_VERSION
574 } // namespace
575