system_error.cc revision 1.1.1.12
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
44namespace
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      };
55      constexpr constant_init() : obj() { }
56
57      ~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*
63    name() const noexcept final
64    { return "generic"; }
65
66    _GLIBCXX_DEFAULT_ABI_TAG
67    string
68    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
77    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*
86    name() const noexcept final
87    { return "system"; }
88
89    _GLIBCXX_DEFAULT_ABI_TAG
90    string
91    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
123    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
519    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
526namespace std _GLIBCXX_VISIBILITY(default)
527{
528_GLIBCXX_BEGIN_NAMESPACE_VERSION
529
530  void
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&
539  _V2::system_category() noexcept { return system_category_instance.obj; }
540
541  const error_category&
542  _V2::generic_category() noexcept { return generic_category_instance.obj; }
543
544  system_error::~system_error() = default;
545
546  error_condition
547  error_category::default_error_condition(int __i) const noexcept
548  { return error_condition(__i, *this); }
549
550  bool
551  error_category::equivalent(int __i,
552			     const error_condition& __cond) const noexcept
553  { return default_error_condition(__i) == __cond; }
554
555  bool
556  error_category::equivalent(const error_code& __code, int __i) const noexcept
557  { return *this == __code.category() && __code.value() == __i; }
558
559  error_condition
560  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
566  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