Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsystemerror.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <qglobal.h>
7#include <errno.h>
8#if defined(Q_CC_MSVC)
9# include <crtdbg.h>
10#endif
11#ifdef Q_OS_WIN
12# include <qt_windows.h>
13# include <comdef.h>
14#endif
15#ifndef QT_BOOTSTRAPPED
16# include <qcoreapplication.h>
17#endif
18
20
21using namespace Qt::StringLiterals;
22
23#if !defined(Q_OS_WIN) && QT_CONFIG(thread) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) &&
24 defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
25namespace {
26 // There are two incompatible versions of strerror_r:
27 // a) the XSI/POSIX.1 version, which returns an int,
28 // indicating success or not
29 // b) the GNU version, which returns a char*, which may or may not
30 // be the beginning of the buffer we used
31 // The GNU libc manpage for strerror_r says you should use the XSI
32 // version in portable code. However, it's impossible to do that if
33 // _GNU_SOURCE is defined so we use C++ overloading to decide what to do
34 // depending on the return type
35 [[maybe_unused]] static inline QString fromstrerror_helper(int, const QByteArray &buf)
36 {
37 return QString::fromLocal8Bit(buf);
38 }
39 [[maybe_unused]] static inline QString fromstrerror_helper(const char *str, const QByteArray &)
40 {
41 return QString::fromLocal8Bit(str);
42 }
43}
44#endif
45
46#ifdef Q_OS_WIN
47static QString windowsErrorString(int errorCode)
48{
49 QString ret;
50 wchar_t *string = nullptr;
51 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
52 NULL,
53 errorCode,
54 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
55 (LPWSTR)&string,
56 0,
57 NULL);
58 ret = QString::fromWCharArray(string);
59 LocalFree((HLOCAL)string);
60
61 if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
62 ret = QString::fromLatin1("The specified module could not be found.");
63 if (ret.endsWith("\r\n"_L1))
64 ret.chop(2);
65 if (ret.isEmpty())
66 ret = QString::fromLatin1("Unknown error 0x%1.")
67 .arg(unsigned(errorCode), 8, 16, '0'_L1);
68 return ret;
69}
70#endif
71
72static QString standardLibraryErrorString(int errorCode)
73{
74 const char *s = nullptr;
75 QString ret;
76 switch (errorCode) {
77 case 0:
78 break;
79 case EACCES:
80 s = QT_TRANSLATE_NOOP("QIODevice", "Permission denied");
81 break;
82 case EMFILE:
83 s = QT_TRANSLATE_NOOP("QIODevice", "Too many open files");
84 break;
85 case ENOENT:
86 s = QT_TRANSLATE_NOOP("QIODevice", "No such file or directory");
87 break;
88 case ENOSPC:
89 s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
90 break;
91 default: {
92 #if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
93 QByteArray buf(1024, Qt::Uninitialized);
94 ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
95 #else
96 ret = QString::fromLocal8Bit(strerror(errorCode));
97 #endif
98 break; }
99 }
100 if (s) {
101#ifndef QT_BOOTSTRAPPED
102 ret = QCoreApplication::translate("QIODevice", s);
103#else
104 ret = QString::fromLatin1(s);
105#endif
106 }
107 return ret.trimmed();
108}
109
110QString QSystemError::string(ErrorScope errorScope, int errorCode)
111{
112 switch (errorScope) {
113 case NativeError:
114#if defined(Q_OS_WIN)
115 return windowsErrorString(errorCode);
116#endif // else unix: native and standard library are the same
117 case StandardLibraryError:
118 return standardLibraryErrorString(errorCode);
119 default:
120 qWarning("invalid error scope");
121 Q_FALLTHROUGH();
122 case NoError:
123 return u"No error"_s;
124 }
125}
126
127QString QSystemError::stdString(int errorCode)
128{
129 return standardLibraryErrorString(errorCode == -1 ? errno : errorCode);
130}
131
132#ifdef Q_OS_WIN
133QString QSystemError::windowsString(int errorCode)
134{
135 return windowsErrorString(errorCode == -1 ? GetLastError() : errorCode);
136}
137
138QString QSystemError::windowsComString(HRESULT hr)
139{
140 const _com_error comError(hr);
141 QString result = u"COM error 0x"_s + QString::number(ulong(hr), 16);
142 if (const wchar_t *msg = comError.ErrorMessage())
143 result += u": "_s + QString::fromWCharArray(msg);
144 return result;
145}
146
147QString qt_error_string(int code)
148{
149 return windowsErrorString(code == -1 ? GetLastError() : code);
150}
151#else
152QString qt_error_string(int code)
153{
154 return standardLibraryErrorString(code == -1 ? errno : code);
155}
156#endif
157
158QT_END_NAMESPACE
Combined button and popup list for selecting options.
QString qt_error_string(int code)
static QString standardLibraryErrorString(int errorCode)