Add qunsetenv(), next to qputenv() and friends.

The existing tst_qgetputenv shows that qputenv with an empty value
doesn't lead to the same result on Windows and on Unix, and there was
no way to fully delete an env var on Unix (which is needed for some
env vars where not-set and empty are different, such as TZ,
see `man tzset`).
This is also why qglobal has qEnvironmentVariableIsSet() vs
qEnvironmentVariableIsEmpty(), on the getter side.

Qt4's ifdefs around unsetenv in qapplication_x11.cpp show that this is
needed within Qt too (although this particular startup notification code
has to be re-imported into Qt5 still).

Change-Id: I631c8cddbcf933d4b9008f11aefc59f5a3c7c866
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
David Faure 2013-01-12 10:12:47 +01:00 committed by The Qt Project
parent ee317360e3
commit 574e5cf9c5
3 changed files with 45 additions and 0 deletions

View File

@ -2171,6 +2171,10 @@ bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT
\a varName. It will create the variable if it does not exist. It
returns 0 if the variable could not be set.
Calling qputenv with an empty value removes the environment variable on
Windows, and makes it set (but empty) on Unix. Prefer using qunsetenv()
for fully portable behavior.
\note qputenv() was introduced because putenv() from the standard
C library was deprecated in VC2005 (and later versions). qputenv()
uses the replacement function in VC, and calls the standard C
@ -2197,6 +2201,39 @@ bool qputenv(const char *varName, const QByteArray& value)
#endif
}
/*!
\relates <QtGlobal>
This function deletes the variable \a varName from the environment.
Returns true on success.
\since 5.1
\sa qputenv(), qgetenv()
*/
bool qunsetenv(const char *varName)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
return _putenv_s(varName, "") == 0;
#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4)
// POSIX.1-2001 and BSD have unsetenv
return unsetenv(varName) == 0;
#elif defined(Q_CC_MINGW)
// On mingw, putenv("var=") removes "var" from the environment
QByteArray buffer(varName);
buffer += '=';
return putenv(buffer.constData()) == 0;
#else
// Fallback to putenv("var=") which will insert an empty var into the
// environment and leak it
QByteArray buffer(varName);
buffer += '=';
char *envVar = qstrdup(buffer.constData());
return putenv(envVar) == 0;
#endif
}
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD)
# if defined(Q_OS_INTEGRITY) && defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 500)

View File

@ -934,6 +934,7 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
class QByteArray;
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
Q_CORE_EXPORT bool qunsetenv(const char *varName);
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT;
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT;

View File

@ -75,6 +75,13 @@ void tst_QGetPutEnv::getSetCheck()
QVERIFY(result == "supervalue");
qputenv(varName,QByteArray());
// Now test qunsetenv
QVERIFY(qunsetenv(varName));
QVERIFY(!qEnvironmentVariableIsSet(varName));
QVERIFY(qEnvironmentVariableIsEmpty(varName));
result = qgetenv(varName);
QCOMPARE(result, QByteArray());
}
QTEST_MAIN(tst_QGetPutEnv)