1 // <system_error> implementation file
3 // Copyright (C) 2007-2023 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 #define _GLIBCXX_USE_CXX11_ABI 1
27 #define __sso_string __sso_stringxxx
29 #include <system_error>
30 #include <bits/functexcept.h>
35 #if defined(_WIN32) && !defined(__CYGWIN__)
36 #define WIN32_LEAN_AND_MEAN
41 #if __has_cpp_attribute(clang::require_constant_initialization)
42 # define __constinit [[clang::require_constant_initialization]]
49 #if _GLIBCXX_HAVE_STRERROR_R
50 // Handle the result of POSIX strerror_r.
52 use_strerror_result(int res
, char* buf
, std::size_t bufsz
,
53 std::size_t& nextbufsz
)
55 if (res
== 0) // Success.
56 return std::strlen(buf
);
58 if (res
== ERANGE
) // Buffer too small to hold result string.
60 nextbufsz
= 2 * bufsz
;
63 // else res == EINVAL, unknown error.
64 if (*buf
== '\0') // No result string written to buffer.
66 const char msg
[] = "Unknown error";
67 std::memcpy(buf
, msg
, sizeof(msg
) - 1);
68 return sizeof(msg
) - 1;
70 else // An "unknown error" string was already written to the buffer.
71 return std::strlen(buf
);
74 // Handle the result of GNU strerror_r.
76 use_strerror_result(char* res
, char* buf
, std::size_t bufsz
,
77 std::size_t& nextbufsz
)
79 if (res
== buf
) // Result string written to the buffer.
80 return std::strlen(res
);
82 // Static result string returned, must be copied to the buffer.
83 std::size_t len
= std::strlen(res
);
86 std::strcpy(buf
, res
);
90 // Reallocate and try again:
95 string
strerror_string(int err
)
97 // Estimate maximum length of strerror strings (including "Unknown error").
98 // Any excess capacity here can be used by std::system_error constructors
99 // when concatenating strings.
100 std::size_t len
= 60;
103 s
.__resize_and_overwrite(len
, [err
, &len
](char* p
, std::size_t n
) {
105 return use_strerror_result(strerror_r(err
, p
, n
), p
, n
, len
);
111 string
strerror_string(int err
)
113 return strerror(err
); // XXX Not thread-safe.
123 constexpr constant_init() : obj() { }
125 ~constant_init() { /* do nothing, union member is not destroyed */ }
128 struct generic_error_category final
: public std::error_category
131 name() const noexcept final
132 { return "generic"; }
134 _GLIBCXX_DEFAULT_ABI_TAG
136 message(int i
) const final
137 { return strerror_string(i
); }
139 // Override this to avoid a virtual call to default_error_condition(i).
141 equivalent(int i
, const std::error_condition
& cond
) const noexcept final
142 { return i
== cond
.value() && *this == cond
.category(); }
145 __constinit constant_init
<generic_error_category
> generic_category_instance
{};
147 struct system_error_category final
: public std::error_category
150 name() const noexcept final
153 _GLIBCXX_DEFAULT_ABI_TAG
155 message(int i
) const final
157 #if defined(_WIN32) && !defined(__CYGWIN__)
160 = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
161 | FORMAT_MESSAGE_ALLOCATE_BUFFER
,
165 reinterpret_cast<LPTSTR
>(&buf
),
171 void operator()(void* p
) const { ::LocalFree(p
); }
173 std::unique_ptr
<char[], deleter
> guard(buf
);
174 if (len
> 3 && !__builtin_memcmp(buf
+ len
- 3, ".\r\n", 3)) [[likely
]]
176 return string(buf
, len
);
178 return string("Unknown error code");
180 return strerror_string(i
);
185 default_error_condition(int ev
) const noexcept final
187 // Use generic category for all known POSIX errno values (including zero)
188 // and system category otherwise.
191 #if defined(_WIN32) && !defined(__CYGWIN__)
193 return {0, generic_category_instance
.obj
};
194 // Convert Windows error code into a corresponding POSIX errno value.
195 #define X(w, e) case ERROR_##w: return {e, generic_category_instance.obj};
196 // This list is based on Cygwin's winsup/cygwin/errno.cc
197 X (ACCESS_DENIED
, EACCES
);
198 X (ACTIVE_CONNECTIONS
, EAGAIN
);
199 X (ALREADY_EXISTS
, EEXIST
);
200 X (BAD_DEVICE
, ENODEV
);
201 X (BAD_EXE_FORMAT
, ENOEXEC
);
202 X (BAD_NETPATH
, ENOENT
);
203 X (BAD_NET_NAME
, ENOENT
);
204 X (BAD_NET_RESP
, ENOSYS
);
205 X (BAD_PATHNAME
, ENOENT
);
206 X (BAD_PIPE
, EINVAL
);
207 X (BAD_UNIT
, ENODEV
);
208 X (BAD_USERNAME
, EINVAL
);
209 X (BEGINNING_OF_MEDIA
, EIO
);
210 X (BROKEN_PIPE
, EPIPE
);
213 X (CALL_NOT_IMPLEMENTED
, ENOSYS
);
214 X (CANCELLED
, EINTR
);
215 X (CANNOT_MAKE
, EPERM
);
216 X (CHILD_NOT_COMPLETE
, EBUSY
);
217 X (COMMITMENT_LIMIT
, EAGAIN
);
218 X (CONNECTION_REFUSED
, ECONNREFUSED
);
220 X (DEVICE_DOOR_OPEN
, EIO
);
221 X (DEVICE_IN_USE
, EAGAIN
);
222 X (DEVICE_REQUIRES_CLEANING
, EIO
);
223 X (DEV_NOT_EXIST
, ENOENT
);
224 X (DIRECTORY
, ENOTDIR
);
225 X (DIR_NOT_EMPTY
, ENOTEMPTY
);
226 X (DISK_CORRUPT
, EIO
);
228 X (DISK_FULL
, ENOSPC
);
230 X (DS_GENERIC_ERROR
, EIO
);
232 X (END_OF_MEDIA
, ENOSPC
);
234 X (EOM_OVERFLOW
, EIO
);
235 X (EXE_MACHINE_TYPE_MISMATCH
, ENOEXEC
);
236 X (EXE_MARKED_INVALID
, ENOEXEC
);
237 X (FILEMARK_DETECTED
, EIO
);
238 X (FILENAME_EXCED_RANGE
, ENAMETOOLONG
);
239 X (FILE_CORRUPT
, EEXIST
);
240 X (FILE_EXISTS
, EEXIST
);
241 X (FILE_INVALID
, ENXIO
);
242 X (FILE_NOT_FOUND
, ENOENT
);
244 X (HANDLE_DISK_FULL
, ENOSPC
);
246 X (INVALID_ADDRESS
, EINVAL
);
247 X (INVALID_AT_INTERRUPT_TIME
, EINTR
);
248 X (INVALID_BLOCK_LENGTH
, EIO
);
249 X (INVALID_DATA
, EINVAL
);
250 X (INVALID_DRIVE
, ENODEV
);
251 X (INVALID_EA_NAME
, EINVAL
);
252 X (INVALID_EXE_SIGNATURE
, ENOEXEC
);
253 X (INVALID_HANDLE
, EBADF
);
254 X (INVALID_NAME
, ENOENT
);
255 X (INVALID_PARAMETER
, EINVAL
);
256 X (INVALID_SIGNAL_NUMBER
, EINVAL
);
257 X (IOPL_NOT_ENABLED
, ENOEXEC
);
259 X (IO_INCOMPLETE
, EAGAIN
);
260 X (IO_PENDING
, EAGAIN
);
261 X (LOCK_VIOLATION
, EBUSY
);
262 X (MAX_THRDS_REACHED
, EAGAIN
);
263 X (META_EXPANSION_TOO_LONG
, EINVAL
);
264 X (MOD_NOT_FOUND
, ENOENT
);
265 X (MORE_DATA
, EMSGSIZE
);
266 X (NEGATIVE_SEEK
, EINVAL
);
267 X (NETNAME_DELETED
, ENOENT
);
268 X (NOACCESS
, EFAULT
);
269 X (NONE_MAPPED
, EINVAL
);
270 X (NONPAGED_SYSTEM_RESOURCES
, EAGAIN
);
271 X (NOT_ENOUGH_MEMORY
, ENOMEM
);
272 X (NOT_ENOUGH_QUOTA
, EIO
);
274 X (NOT_OWNER
, EPERM
);
276 X (NOT_OWNER
, EACCES
);
278 X (NOT_SAME_DEVICE
, EXDEV
);
279 X (NOT_SUPPORTED
, ENOSYS
);
281 X (NO_DATA_DETECTED
, EIO
);
282 X (NO_MORE_SEARCH_HANDLES
, ENFILE
);
283 X (NO_PROC_SLOTS
, EAGAIN
);
284 X (NO_SIGNAL_SENT
, EIO
);
285 X (NO_SYSTEM_RESOURCES
, EFBIG
);
286 X (NO_TOKEN
, EINVAL
);
287 X (OPEN_FAILED
, EIO
);
288 X (OPEN_FILES
, EAGAIN
);
289 X (OUTOFMEMORY
, ENOMEM
);
290 X (PAGED_SYSTEM_RESOURCES
, EAGAIN
);
291 X (PAGEFILE_QUOTA
, EAGAIN
);
292 X (PATH_NOT_FOUND
, ENOENT
);
293 X (PIPE_BUSY
, EBUSY
);
294 X (PIPE_CONNECTED
, EBUSY
);
295 X (POSSIBLE_DEADLOCK
, EDEADLK
);
296 X (PRIVILEGE_NOT_HELD
, EPERM
);
297 X (PROCESS_ABORTED
, EFAULT
);
298 X (PROC_NOT_FOUND
, ESRCH
);
299 X (SECTOR_NOT_FOUND
, EINVAL
);
301 X (SERVICE_REQUEST_TIMEOUT
, EBUSY
);
302 X (SETMARK_DETECTED
, EIO
);
303 X (SHARING_BUFFER_EXCEEDED
, ENOLCK
);
304 X (SHARING_VIOLATION
, EBUSY
);
305 X (SIGNAL_PENDING
, EBUSY
);
306 X (SIGNAL_REFUSED
, EIO
);
307 X (THREAD_1_INACTIVE
, EINVAL
);
309 X (TOO_MANY_LINKS
, EMLINK
);
310 X (TOO_MANY_OPEN_FILES
, EMFILE
);
311 X (UNEXP_NET_ERR
, EIO
);
312 X (WORKING_SET_QUOTA
, EAGAIN
);
313 X (WRITE_PROTECT
, EROFS
);
316 #elif defined __AVR__
317 // avr-libc only defines a few distinct error numbers. Most <errno.h>
318 // constants are not usable in #if directives and have the same value.
324 return std::error_condition(ev
, generic_category_instance
.obj
);
326 // List of errno macros from [cerrno.syn].
327 // C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX.
328 // They expand to integer constant expressions with type int,
329 // and distinct positive values, suitable for use in #if directives.
330 // POSIX adds more macros (but they're not defined on all targets,
331 // see config/os/.../error_constants.h), and POSIX allows
332 // EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP.
495 #if defined ENOTEMPTY && (!defined EEXIST || ENOTEMPTY != EEXIST)
496 // AIX sometimes uses the same value for EEXIST and ENOTEMPTY
499 #ifdef ENOTRECOVERABLE
500 case ENOTRECOVERABLE
:
505 #if defined ENOTSUP && (!defined ENOSYS || ENOTSUP != ENOSYS)
506 // zTPF uses the same value for ENOSYS and ENOTSUP
515 #if defined EOPNOTSUPP && (!defined ENOTSUP || EOPNOTSUPP != ENOTSUP)
533 #ifdef EPROTONOSUPPORT
534 case EPROTONOSUPPORT
:
558 #if defined EWOULDBLOCK && (!defined EAGAIN || EWOULDBLOCK != EAGAIN)
565 return std::error_condition(ev
, generic_category_instance
.obj
);
567 /* Additional system-dependent mappings from non-standard error codes
568 * to one of the POSIX values above would go here, e.g.
570 return std::error_condition(EINVAL, std::generic_category());
575 return std::error_condition(ev
, *this);
579 // Override this to avoid a virtual call to default_error_condition(i).
581 equivalent(int i
, const std::error_condition
& cond
) const noexcept final
582 { return system_error_category::default_error_condition(i
) == cond
; }
585 __constinit constant_init
<system_error_category
> system_category_instance
{};
588 namespace std
_GLIBCXX_VISIBILITY(default)
590 _GLIBCXX_BEGIN_NAMESPACE_VERSION
593 __throw_system_error(int __i
__attribute__((unused
)))
595 _GLIBCXX_THROW_OR_ABORT(system_error(__i
, generic_category_instance
.obj
));
598 error_category::~error_category() = default;
600 _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2
)
602 const error_category
&
603 system_category() noexcept
{ return system_category_instance
.obj
; }
605 const error_category
&
606 generic_category() noexcept
{ return generic_category_instance
.obj
; }
608 _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2
)
610 system_error::~system_error() = default;
613 error_category::default_error_condition(int __i
) const noexcept
614 { return error_condition(__i
, *this); }
617 error_category::equivalent(int __i
,
618 const error_condition
& __cond
) const noexcept
619 { return default_error_condition(__i
) == __cond
; }
622 error_category::equivalent(const error_code
& __code
, int __i
) const noexcept
623 { return *this == __code
.category() && __code
.value() == __i
; }
626 error_code::default_error_condition() const noexcept
627 { return category().default_error_condition(value()); }
629 #if _GLIBCXX_USE_CXX11_ABI
630 // Return error_category::message() as a COW string
632 error_category::_M_message(int i
) const
634 string msg
= this->message(i
);
635 return {msg
.c_str(), msg
.length()};
639 _GLIBCXX_END_NAMESPACE_VERSION