aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/c++11/system_error.cc156
1 files changed, 156 insertions, 0 deletions
diff --git a/libstdc++-v3/src/c++11/system_error.cc b/libstdc++-v3/src/c++11/system_error.cc
index 7fc178a..f1cfc03 100644
--- a/libstdc++-v3/src/c++11/system_error.cc
+++ b/libstdc++-v3/src/c++11/system_error.cc
@@ -32,6 +32,11 @@
#include <errno.h>
#undef __sso_string
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <memory>
+#include <windows.h>
+#endif
+
namespace
{
using std::string;
@@ -81,9 +86,33 @@ namespace
string
message(int i) const final
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char* buf = nullptr;
+ auto len
+ = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ nullptr,
+ i,
+ LANG_USER_DEFAULT,
+ reinterpret_cast<LPTSTR>(&buf),
+ 0,
+ nullptr);
+ if (len > 0)
+ {
+ struct deleter {
+ void operator()(void* p) const { ::LocalFree(p); }
+ };
+ std::unique_ptr<char[], deleter> guard(buf);
+ if (len > 3 && !__builtin_memcmp(buf + len - 3, ".\r\n", 3)) [[likely]]
+ len -= 3;
+ return string(buf, len);
+ }
+ return string("Unknown error code");
+#else
// XXX locale issues: how does one get or set loc.
// _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
return string(strerror(i));
+#endif
}
std::error_condition
@@ -93,6 +122,132 @@ namespace
// and system category otherwise.
switch (ev)
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ case 0:
+ return {0, generic_category_instance.obj};
+ // Convert Windows error code into a corresponding POSIX errno value.
+#define X(w, e) case ERROR_##w: return {e, generic_category_instance.obj};
+ // This list is based on Cygwin's winsup/cygwin/errno.cc
+ X (ACCESS_DENIED, EACCES);
+ X (ACTIVE_CONNECTIONS, EAGAIN);
+ X (ALREADY_EXISTS, EEXIST);
+ X (BAD_DEVICE, ENODEV);
+ X (BAD_EXE_FORMAT, ENOEXEC);
+ X (BAD_NETPATH, ENOENT);
+ X (BAD_NET_NAME, ENOENT);
+ X (BAD_NET_RESP, ENOSYS);
+ X (BAD_PATHNAME, ENOENT);
+ X (BAD_PIPE, EINVAL);
+ X (BAD_UNIT, ENODEV);
+ X (BAD_USERNAME, EINVAL);
+ X (BEGINNING_OF_MEDIA, EIO);
+ X (BROKEN_PIPE, EPIPE);
+ X (BUSY, EBUSY);
+ X (BUS_RESET, EIO);
+ X (CALL_NOT_IMPLEMENTED, ENOSYS);
+ X (CANCELLED, EINTR);
+ X (CANNOT_MAKE, EPERM);
+ X (CHILD_NOT_COMPLETE, EBUSY);
+ X (COMMITMENT_LIMIT, EAGAIN);
+ X (CONNECTION_REFUSED, ECONNREFUSED);
+ X (CRC, EIO);
+ X (DEVICE_DOOR_OPEN, EIO);
+ X (DEVICE_IN_USE, EAGAIN);
+ X (DEVICE_REQUIRES_CLEANING, EIO);
+ X (DEV_NOT_EXIST, ENOENT);
+ X (DIRECTORY, ENOTDIR);
+ X (DIR_NOT_EMPTY, ENOTEMPTY);
+ X (DISK_CORRUPT, EIO);
+#ifdef ENOSPC
+ X (DISK_FULL, ENOSPC);
+#endif
+ X (DS_GENERIC_ERROR, EIO);
+#ifdef ENOSPC
+ X (END_OF_MEDIA, ENOSPC);
+#endif
+ X (EOM_OVERFLOW, EIO);
+ X (EXE_MACHINE_TYPE_MISMATCH, ENOEXEC);
+ X (EXE_MARKED_INVALID, ENOEXEC);
+ X (FILEMARK_DETECTED, EIO);
+ X (FILENAME_EXCED_RANGE, ENAMETOOLONG);
+ X (FILE_CORRUPT, EEXIST);
+ X (FILE_EXISTS, EEXIST);
+ X (FILE_INVALID, ENXIO);
+ X (FILE_NOT_FOUND, ENOENT);
+#ifdef ENOSPC
+ X (HANDLE_DISK_FULL, ENOSPC);
+#endif
+ X (INVALID_ADDRESS, EINVAL);
+ X (INVALID_AT_INTERRUPT_TIME, EINTR);
+ X (INVALID_BLOCK_LENGTH, EIO);
+ X (INVALID_DATA, EINVAL);
+ X (INVALID_DRIVE, ENODEV);
+ X (INVALID_EA_NAME, EINVAL);
+ X (INVALID_EXE_SIGNATURE, ENOEXEC);
+ X (INVALID_HANDLE, EBADF);
+ X (INVALID_NAME, ENOENT);
+ X (INVALID_PARAMETER, EINVAL);
+ X (INVALID_SIGNAL_NUMBER, EINVAL);
+ X (IOPL_NOT_ENABLED, ENOEXEC);
+ X (IO_DEVICE, EIO);
+ X (IO_INCOMPLETE, EAGAIN);
+ X (IO_PENDING, EAGAIN);
+ X (LOCK_VIOLATION, EBUSY);
+ X (MAX_THRDS_REACHED, EAGAIN);
+ X (META_EXPANSION_TOO_LONG, EINVAL);
+ X (MOD_NOT_FOUND, ENOENT);
+ X (MORE_DATA, EMSGSIZE);
+ X (NEGATIVE_SEEK, EINVAL);
+ X (NETNAME_DELETED, ENOENT);
+ X (NOACCESS, EFAULT);
+ X (NONE_MAPPED, EINVAL);
+ X (NONPAGED_SYSTEM_RESOURCES, EAGAIN);
+ X (NOT_ENOUGH_MEMORY, ENOMEM);
+ X (NOT_ENOUGH_QUOTA, EIO);
+#ifdef EPERM
+ X (NOT_OWNER, EPERM);
+#else
+ X (NOT_OWNER, EACCES);
+#endif
+ X (NOT_SAME_DEVICE, EXDEV);
+ X (NOT_SUPPORTED, ENOSYS);
+ X (NO_DATA, EPIPE);
+ X (NO_DATA_DETECTED, EIO);
+ X (NO_MORE_SEARCH_HANDLES, ENFILE);
+ X (NO_PROC_SLOTS, EAGAIN);
+ X (NO_SIGNAL_SENT, EIO);
+ X (NO_SYSTEM_RESOURCES, EFBIG);
+ X (NO_TOKEN, EINVAL);
+ X (OPEN_FAILED, EIO);
+ X (OPEN_FILES, EAGAIN);
+ X (OUTOFMEMORY, ENOMEM);
+ X (PAGED_SYSTEM_RESOURCES, EAGAIN);
+ X (PAGEFILE_QUOTA, EAGAIN);
+ X (PATH_NOT_FOUND, ENOENT);
+ X (PIPE_BUSY, EBUSY);
+ X (PIPE_CONNECTED, EBUSY);
+ X (POSSIBLE_DEADLOCK, EDEADLK);
+ X (PRIVILEGE_NOT_HELD, EPERM);
+ X (PROCESS_ABORTED, EFAULT);
+ X (PROC_NOT_FOUND, ESRCH);
+ X (SECTOR_NOT_FOUND, EINVAL);
+ X (SEEK, EINVAL);
+ X (SERVICE_REQUEST_TIMEOUT, EBUSY);
+ X (SETMARK_DETECTED, EIO);
+ X (SHARING_BUFFER_EXCEEDED, ENOLCK);
+ X (SHARING_VIOLATION, EBUSY);
+ X (SIGNAL_PENDING, EBUSY);
+ X (SIGNAL_REFUSED, EIO);
+ X (THREAD_1_INACTIVE, EINVAL);
+ X (TIMEOUT, EBUSY);
+ X (TOO_MANY_LINKS, EMLINK);
+ X (TOO_MANY_OPEN_FILES, EMFILE);
+ X (UNEXP_NET_ERR, EIO);
+ X (WORKING_SET_QUOTA, EAGAIN);
+ X (WRITE_PROTECT, EROFS);
+#undef X
+
+#else
// List of errno macros from [cerrno.syn].
// C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX.
// They expand to integer constant expressions with type int,
@@ -340,6 +495,7 @@ namespace
return std::error_condition(EINVAL, std::generic_category());
*/
+#endif
default:
return std::error_condition(ev, *this);
}