require strerror_r(), realpath() and unsetenv() from the host

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
Ivailo Monev 2020-01-06 01:26:40 +00:00
parent b08a1960b6
commit 386e6fc3d4
10 changed files with 37 additions and 106 deletions

View file

@ -219,6 +219,12 @@ check_include_file(sys/time.h HAVE_SYS_TIME_H)
# used in qconfig.h
check_type_size(size_t QT_POINTER_SIZE)
# XSI POSIX.1-2001 functions
katie_check_function(strerror_r "string.h")
# POSIX.1-2008 functions
katie_check_function(realpath "stdlib.h")
katie_check_function(unsetenv "stdlib.h")
if(KATIE_COMPILER MATCHES "(gcc|clang)")
set(QT_VISIBILITY_AVAILABLE TRUE)
endif()

View file

@ -6,6 +6,9 @@ set(KATIE_RCC "rcc")
set(KATIE_MOC "bootstrap_moc")
set(KATIE_LRELEASE "lrelease")
include(CheckSymbolExists)
include(CheckFunctionExists)
# a macro to print a dev warning but only when the build type is Debug
macro(KATIE_WARNING MESSAGESTR)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@ -13,6 +16,16 @@ macro(KATIE_WARNING MESSAGESTR)
endif()
endmacro()
macro(KATIE_CHECK_FUNCTION FORFUNCTION FROMHEADER)
check_symbol_exists("${FORFUNCTION}" "${FROMHEADER}" HAVE_${FORFUNCTION})
if(NOT HAVE_${FORFUNCTION})
check_function_exists("${FORFUNCTION}" HAVE_${FORFUNCTION})
endif()
if(NOT HAVE_${FORFUNCTION})
message(SEND_ERROR "check_function_exists(${FORFUNCTION}) failed")
endif()
endmacro()
# a macro to write data to file, does nothing if the file exists and its
# content is the same as the data
macro(KATIE_WRITE_FILE OUTFILE DATA)

View file

@ -1365,12 +1365,7 @@ QString qt_error_string(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
QByteArray buf(1024, '\0');
ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
#else
ret = QString::fromLocal8Bit(strerror(errorCode));
#endif
ret = fromstrerror_helper(errorCode);
break;
}
}

View file

@ -42,55 +42,6 @@
QT_BEGIN_NAMESPACE
/*!
\internal
Returns the canonicalized form of \a path (i.e., with all symlinks
resolved, and all redundant path elements removed.
*/
QString QFileSystemEngine::slowCanonicalized(const QString &path)
{
if (path.isEmpty())
return path;
QFileInfo fi;
const QChar slash(QLatin1Char('/'));
QString tmpPath = path;
int separatorPos = 0;
QSet<QString> nonSymlinks;
QSet<QString> known;
known.insert(path);
do {
separatorPos = tmpPath.indexOf(slash, separatorPos + 1);
QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos);
if (
!nonSymlinks.contains(prefix)) {
fi.setFile(prefix);
if (fi.isSymLink()) {
QString target = fi.readLink();
if(QFileInfo(target).isRelative())
target = fi.absolutePath() + slash + target;
if (separatorPos != -1) {
if (fi.isDir() && !target.endsWith(slash))
target.append(slash);
target.append(tmpPath.mid(separatorPos));
}
tmpPath = QDir::cleanPath(target);
separatorPos = 0;
if (known.contains(tmpPath))
return QString();
known.insert(tmpPath);
} else {
nonSymlinks.insert(prefix);
}
}
} while (separatorPos != -1);
return QDir::cleanPath(tmpPath);
}
static inline bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &data, bool resolvingEntry)
{
if (resolvingEntry) {

View file

@ -90,8 +90,6 @@ public:
static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry,
QFileSystemMetaData &data);
private:
static QString slowCanonicalized(const QString &path);
};
QT_END_NAMESPACE

View file

@ -120,27 +120,12 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
if (entry.isEmpty() || entry.isRoot())
return entry;
#if _POSIX_VERSION < 200809L
// realpath(X,0) is not supported
Q_UNUSED(data);
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else
#if _POSIX_VERSION >= 200801L
char *ret = realpath(entry.nativeFilePath().constData(), (char*)0);
#else
char *ret = static_cast<char*>(malloc(PATH_MAX + 1));
if (realpath(entry.nativeFilePath().constData(), ret) == 0) {
const int savedErrno = errno; // errno is checked below, and free() might change it
free(ret);
errno = savedErrno;
ret = 0;
}
#endif
char *ret = ::realpath(entry.nativeFilePath().constData(), (char*)0);
if (ret) {
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret));
free(ret);
::free(ret);
return QFileSystemEntry(canonicalPath);
} else if (errno == ENOENT) { // file doesn't exist
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
@ -148,7 +133,6 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry();
}
return entry;
#endif
}
//static

View file

@ -59,12 +59,7 @@ static QString standardLibraryErrorString(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
QByteArray buf(1024, '\0');
ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
#else
ret = QString::fromLocal8Bit(strerror(errorCode));
#endif
ret = fromstrerror_helper(errorCode);
break; }
}
if (s) {

View file

@ -7,30 +7,31 @@
# include <zlib.h>
#endif
#include <string.h>
QT_BEGIN_NAMESPACE
// enough space to hold BOM, each char as surrogate pair and terminator
#define QMAXUSTRLEN(X) 4 + (X * 2) + 2
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
// There are two incompatible versions of strerror_r:
// a) the XSI/POSIX.1 version, which returns an int,
// indicating success or not
// b) the GNU version, which returns a char*, which may or may not
// be the beginning of the buffer we used
// The GNU libc manpage for strerror_r says you should use the the XSI
// version in portable code. However, it's impossible to do that if
// _GNU_SOURCE is defined so we use C++ overloading to decide what to do
// depending on the return type
static inline QString fromstrerror_helper(int, const QByteArray &buf)
// version in portable code.
static inline QString fromstrerror_helper(const int errorcode)
{
return QString::fromLocal8Bit(buf.constData());
}
static inline QString fromstrerror_helper(const char *str, const QByteArray &)
{
return QString::fromLocal8Bit(str);
}
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
char errbuf[1024];
::memset(errbuf, '\0', sizeof(errbuf));
::strerror_r(errorcode, errbuf, sizeof(errbuf));
return QString::fromLocal8Bit(errbuf, sizeof(errbuf));
#else
return QString::fromLocal8Bit(::strerror(errorcode));
#endif
}
static inline void report_error(int code, const char *where, const char *what)
{

View file

@ -95,10 +95,6 @@
# include <errno.h>
#endif
#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
# define QT_NO_UNSETENV
#endif
QT_BEGIN_NAMESPACE
//#define X_NOT_BROKEN
@ -1624,13 +1620,7 @@ void qt_init(QApplicationPrivate *priv, int,
qt_x11Data->startupId = getenv("DESKTOP_STARTUP_ID");
if (qt_x11Data->startupId) {
#ifndef QT_NO_UNSETENV
unsetenv("DESKTOP_STARTUP_ID");
#else
// it's a small memory leak, however we won't crash if Qt is
// unloaded and someones tries to use the envoriment.
putenv(strdup("DESKTOP_STARTUP_ID="));
#endif
::unsetenv("DESKTOP_STARTUP_ID");
}
} else {
// read some non-GUI settings when not using the X server...

View file

@ -1081,9 +1081,7 @@ void tst_QDir::homePath()
QVERIFY(!strHome.endsWith('/'));
QByteArray envHome = qgetenv("HOME");
#if !defined(_WRS_KERNEL) // unsetenv is not available on VxWorks DKM mode
unsetenv("HOME");
#endif
::unsetenv("HOME");
QCOMPARE(QDir::homePath(), QDir::rootPath());
qputenv("HOME", envHome);
#endif