check for get_current_dir_name(), fegetenv(), fesetenv(), feclearexcept() and feenableexcept()

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
Ivailo Monev 2020-01-16 19:06:01 +00:00
parent 1c2e5c098d
commit f340ed751e
5 changed files with 76 additions and 60 deletions

View file

@ -232,6 +232,12 @@ katie_check_function(fcvt "stdlib.h")
katie_check_function(ecvt "stdlib.h")
# NetBSD 1.6 and FreeBSD 4.4
katie_check_function(getprogname "stdlib.h")
# GNU
katie_check_function(get_current_dir_name "unistd.h")
katie_check_function(fegetenv "fenv.h")
katie_check_function(fesetenv "fenv.h")
katie_check_function(feclearexcept "fenv.h")
katie_check_function(feenableexcept "fenv.h")
# 64-bit offset alternatives, if any of the functions is not found it will set
# QT_LARGEFILE_SUPPORT to FALSE. QT_LARGEFILE_SUPPORT is used in qconfig.h

View file

@ -17,15 +17,45 @@ macro(KATIE_WARNING MESSAGESTR)
endif()
endmacro()
# a function to check for C function/definition, works for external functions too
function(KATIE_CHECK_DEFINED FORDEFINITION FROMHEADER)
cmake_reset_check_state()
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${ARGN})
check_symbol_exists("${FORDEFINITION}" "${FROMHEADER}" HAVE_${FORDEFINITION})
if(NOT HAVE_${FORDEFINITION})
check_function_exists("${FORDEFINITION}" HAVE_${FORDEFINITION})
endif()
cmake_pop_check_state()
if(NOT HAVE_${FORDEFINITION})
set(compileout "${CMAKE_BINARY_DIR}/${FORDEFINITION}.cpp")
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/modules/katie_check_defined.cpp.cmake"
"${compileout}"
@ONLY
)
try_compile(${FORDEFINITION}_test
"${CMAKE_BINARY_DIR}"
"${compileout}"
COMPILE_DEFINITIONS ${ARGN}
OUTPUT_VARIABLE ${FORDEFINITION}_test_output
)
if(${FORDEFINITION}_test)
message(STATUS "Found ${FORDEFINITION} in: <${FROMHEADER}>")
set(HAVE_${FORDEFINITION} TRUE PARENT_SCOPE)
else()
message(STATUS "Could not find ${FORDEFINITION} in: <${FROMHEADER}>")
set(HAVE_${FORDEFINITION} FALSE PARENT_SCOPE)
endif()
endif()
endfunction()
# a macro to check for function presence in header, if function is found a
# definition is added. note that check_symbol_exists() and
# check_function_exists() cache the result variables so they can be used
# anywhere
macro(KATIE_CHECK_FUNCTION FORFUNCTION FROMHEADER)
check_symbol_exists("${FORFUNCTION}" "${FROMHEADER}" HAVE_${FORFUNCTION})
if(NOT HAVE_${FORFUNCTION})
check_function_exists("${FORFUNCTION}" HAVE_${FORFUNCTION})
endif()
katie_check_defined("${FORFUNCTION}" "${FROMHEADER}")
if(HAVE_${FORFUNCTION})
string(TOUPPER "${FORFUNCTION}" upperfunction)
@ -36,17 +66,11 @@ endmacro()
# a function to check for function with 64-bit offset alternative, sets
# QT_LARGEFILE_SUPPORT to FALSE if not available
function(KATIE_CHECK_FUNCTION64 FORFUNCTION FROMHEADER)
cmake_reset_check_state()
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE)
check_symbol_exists("${FORFUNCTION}" "${FROMHEADER}" HAVE_${FORFUNCTION})
if(NOT HAVE_${FORFUNCTION})
check_function_exists("${FORFUNCTION}" HAVE_${FORFUNCTION})
endif()
katie_check_defined("${FORFUNCTION}" "${FROMHEADER}" -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE)
if(NOT HAVE_${FORFUNCTION})
set(QT_LARGEFILE_SUPPORT FALSE PARENT_SCOPE)
endif()
cmake_pop_check_state()
endfunction()
# a macro to write data to file, does nothing if the file exists and its

View file

@ -0,0 +1,9 @@
#include <stdio.h>
#include <@FROMHEADER@>
int main() {
#ifndef @FORDEFINITION@
return printf("%p\n", &@FORDEFINITION@);
#endif
return 0;
}

View file

@ -38,9 +38,6 @@
#include "qfileinfo.h"
#include "qcore_unix_p.h"
#include <stdlib.h> // for realpath()
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
@ -49,6 +46,10 @@
# include <sys/sendfile.h>
#endif
#ifndef PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
#endif
QT_BEGIN_NAMESPACE
bool QFileSystemEngine::isCaseSensitive()
@ -59,45 +60,21 @@ bool QFileSystemEngine::isCaseSensitive()
//static
QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
{
#if defined(__GLIBC__) && !defined(PATH_MAX)
#define PATH_CHUNK_SIZE 256
char *s = 0;
int len = -1;
int size = PATH_CHUNK_SIZE;
while (1) {
s = (char *) ::realloc(s, size);
Q_CHECK_PTR(s);
len = ::readlink(link.nativeFilePath().constData(), s, size);
if (len < 0) {
::free(s);
break;
}
if (len < size) {
break;
}
size *= 2;
}
#else
char s[PATH_MAX+1];
int len = readlink(link.nativeFilePath().constData(), s, PATH_MAX);
#endif
char readlinkbuf[PATH_MAX];
int len = ::readlink(link.nativeFilePath().constData(), readlinkbuf, sizeof(readlinkbuf));
if (len > 0) {
QString ret;
if (!data.hasFlags(QFileSystemMetaData::DirectoryType))
fillMetaData(link, data, QFileSystemMetaData::DirectoryType);
if (data.isDirectory() && s[0] != '/') {
if (data.isDirectory() && readlinkbuf[0] != '/') {
QDir parent(link.filePath());
parent.cdUp();
ret = parent.path();
if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
ret += QLatin1Char('/');
}
s[len] = '\0';
ret += QFile::decodeName(QByteArray(s));
#if defined(__GLIBC__) && !defined(PATH_MAX)
::free(s);
#endif
readlinkbuf[len] = '\0';
ret += QFile::decodeName(QByteArray(readlinkbuf));
if (!ret.startsWith(QLatin1Char('/'))) {
if (link.filePath().startsWith(QLatin1Char('/'))) {
@ -172,16 +149,16 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
//static
QString QFileSystemEngine::resolveUserName(uint userId)
{
struct passwd *pw = 0;
#if !defined(QT_NO_THREAD) && defined(QT_HAVE_GETPWUID_R)
int size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
char buf[size_max];
struct passwd entry;
getpwuid_r(userId, &entry, buf, size_max, &pw);
struct passwd *pw = Q_NULLPTR;
::getpwuid_r(userId, &entry, buf, size_max, &pw);
#else
pw = getpwuid(userId);
struct passwd *pw = ::getpwuid(userId);
#endif
if (pw)
return QFile::decodeName(QByteArray(pw->pw_name));
@ -191,16 +168,16 @@ QString QFileSystemEngine::resolveUserName(uint userId)
//static
QString QFileSystemEngine::resolveGroupName(uint groupId)
{
struct group *gr = 0;
#if !defined(QT_NO_THREAD) && defined(QT_HAVE_GETGRGID_R)
int size_max = sysconf(_SC_GETGR_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
char buf[size_max];
struct group entry;
getgrgid_r(groupId, &entry, buf, size_max, &gr);
struct group *gr = Q_NULLPTR;
::getgrgid_r(groupId, &entry, buf, size_max, &gr);
#else
gr = getgrgid(groupId);
struct group *gr = ::getgrgid(groupId);
#endif
if (gr)
return QFile::decodeName(QByteArray(gr->gr_name));
@ -511,20 +488,20 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &path)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QFileSystemEntry result;
#if defined(__GLIBC__)
#ifdef QT_HAVE_GET_CURRENT_DIR_NAME
#define GETCWDFUNCNAME "get_current_dir_name"
char *currentName = ::get_current_dir_name();
if (currentName) {
result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
::free(currentName);
char *currentdir = ::get_current_dir_name();
if (currentdir) {
result = QFileSystemEntry(QByteArray(currentdir), QFileSystemEntry::FromNativePath());
::free(currentdir);
}
#else
#define GETCWDFUNCNAME "getcwd"
char currentName[PATH_MAX+1];
if (::getcwd(currentName, PATH_MAX)) {
result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
char getcwdbuffer[PATH_MAX];
if (::getcwd(getcwdbuffer, sizeof(getcwdbuffer))) {
result = QFileSystemEntry(QByteArray(getcwdbuffer), QFileSystemEntry::FromNativePath());
}
#endif // __GLIBC__
#endif // QT_HAVE_GET_CURRENT_DIR_NAME
#ifndef QT_NO_DEBUG
if (result.isEmpty())

View file

@ -44,8 +44,8 @@
#include <float.h>
#include <stdlib.h>
// TODO: should check if feenableexcept is available
#if defined(Q_OS_LINUX) && defined(__GLIBC__)
#if defined(Q_OS_LINUX) && defined(QT_HAVE_FEGETENV) && defined(QT_HAVE_FESETENV) \
&& defined(QT_HAVE_FECLEAREXCEPT) && defined(QT_HAVE_FEENABLEEXCEPT)
# define TEST_FP_EXCEPTION
#endif