summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2022-08-03 19:23:28 +0200
committerMarc Mutz <marc.mutz@qt.io>2022-08-06 14:21:46 +0000
commit5ff71637968c70f138d8ea6cc24e61c1608f2187 (patch)
tree4b4f605969497961e70ad311b2ebed3d0b4060e3 /src
parent5b62970b9441717670a1756b858c500004dfdfe0 (diff)
qputenv: port to QByteArrayView
The vast majority of in-tree users pass simple and short C string literals as the value. By porting to QByteArrayView, we document that we'll accept non-NUL-terminated data, and do the NUL-termination internally, using SSO'ed std::string, saving memory allocations in the common case of short strings. I didn't bother to check which direction std::string takes for nullptrs these days (there was a change accepted in that area for C++20 or 23), so play it safe and protect against them. Follow-up to Task-number: QTBUG-105302 Change-Id: I2369acc62f1d5cbc26135396cfe0602d8c75300c Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/compat/removed_api.cpp7
-rw-r--r--src/corelib/global/qenvironmentvariables.cpp25
-rw-r--r--src/corelib/global/qenvironmentvariables.h6
-rw-r--r--src/gui/opengl/platform/unix/qglxconvenience.cpp2
4 files changed, 27 insertions, 13 deletions
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp
index 2b864ad41f..aa1a496f0f 100644
--- a/src/corelib/compat/removed_api.cpp
+++ b/src/corelib/compat/removed_api.cpp
@@ -285,6 +285,13 @@ QT_WARNING_POP
#if QT_CORE_REMOVED_SINCE(6, 5)
+#include "qenvironmentvariables.h"
+
+bool qputenv(const char *varName, const QByteArray &value)
+{
+ return qputenv(varName, qToByteArrayViewIgnoringNull(value));
+}
+
#include "qmetatype.h"
int QMetaType::idHelper() const
diff --git a/src/corelib/global/qenvironmentvariables.cpp b/src/corelib/global/qenvironmentvariables.cpp
index d3d963e52e..4860913327 100644
--- a/src/corelib/global/qenvironmentvariables.cpp
+++ b/src/corelib/global/qenvironmentvariables.cpp
@@ -243,6 +243,7 @@ bool qEnvironmentVariableIsSet(const char *varName) noexcept
}
/*!
+ \fn bool qputenv(const char *varName, QByteArrayView value)
\relates <QEnvironmentVariables>
This function sets the \a value of the environment variable named
@@ -258,30 +259,30 @@ bool qEnvironmentVariableIsSet(const char *varName) noexcept
uses the replacement function in VC, and calls the standard C
library's implementation on all other platforms.
+ \note In Qt versions prior to 6.5, the \a value argument was QByteArray,
+ not QByteArrayView.
+
\sa qgetenv(), qEnvironmentVariable()
*/
-bool qputenv(const char *varName, const QByteArray &value)
+bool qputenv(const char *varName, QByteArrayView raw)
{
- // protect against non-NUL-terminated QByteArrays:
- if (!const_cast<QByteArray&>(value).data_ptr()->isMutable()) {
- QByteArray copy(value);
- copy.reserve(copy.size() + 1); // ensures NUL termination (and isMutable() even for size==0
- // (unlike detach()) to avoid infinite recursion)
- return qputenv(varName, copy);
- }
+ auto protect = [](const char *str) { return str ? str : ""; };
+
+ std::string value{protect(raw.data()), size_t(raw.size())}; // NUL-terminates w/SSO
#if defined(Q_CC_MSVC)
const auto locker = qt_scoped_lock(environmentMutex);
- return _putenv_s(varName, value.constData()) == 0;
+ return _putenv_s(varName, value.data()) == 0;
#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU)
// POSIX.1-2001 has setenv
const auto locker = qt_scoped_lock(environmentMutex);
- return setenv(varName, value.constData(), true) == 0;
+ return setenv(varName, value.data(), true) == 0;
#else
- QByteArray buffer(varName);
+ std::string buffer;
+ buffer += protect(varName);
buffer += '=';
buffer += value;
- char *envVar = qstrdup(buffer.constData());
+ char *envVar = qstrdup(buffer.data());
int result = [&] {
const auto locker = qt_scoped_lock(environmentMutex);
return putenv(envVar);
diff --git a/src/corelib/global/qenvironmentvariables.h b/src/corelib/global/qenvironmentvariables.h
index cde51c9ba1..78fea255d3 100644
--- a/src/corelib/global/qenvironmentvariables.h
+++ b/src/corelib/global/qenvironmentvariables.h
@@ -5,6 +5,7 @@
#define QENVIRONMENTVARIABLES_H
#include <QtCore/qglobal.h>
+#include <QtCore/qtdeprecationmarkers.h>
#if 0
#pragma qt_class(QEnvironmentVariables)
@@ -14,11 +15,16 @@
QT_BEGIN_NAMESPACE
class QByteArray;
+class QByteArrayView;
+
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
// need it as two functions because QString is only forward-declared here
Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName);
Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName, const QString &defaultValue);
+#if QT_CORE_REMOVED_SINCE(6, 5)
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray &value);
+#endif
+Q_CORE_EXPORT bool qputenv(const char *varName, QByteArrayView value);
Q_CORE_EXPORT bool qunsetenv(const char *varName);
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept;
diff --git a/src/gui/opengl/platform/unix/qglxconvenience.cpp b/src/gui/opengl/platform/unix/qglxconvenience.cpp
index a756caf343..ce70818042 100644
--- a/src/gui/opengl/platform/unix/qglxconvenience.cpp
+++ b/src/gui/opengl/platform/unix/qglxconvenience.cpp
@@ -124,7 +124,7 @@ struct QXcbSoftwareOpenGLEnforcer {
}
if (forceSoftwareOpenGL)
- qputenv("LIBGL_ALWAYS_SOFTWARE", QByteArrayLiteral("1"));
+ qputenv("LIBGL_ALWAYS_SOFTWARE", "1");
}
~QXcbSoftwareOpenGLEnforcer() {