Linux: Remove our use of syscall() for statx(2) and renameat2(2)

Those system calls are present in glibc 2.28. Instead of using
syscall(3) to place the system calls directly, let's use only the glibc
functions. That also means we no longer accept ENOSYS from either
function, if they were detected in glibc.

Change-Id: I44e7d800c68141bdaae0fffd1555b4b8fe63786b
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
This commit is contained in:
Thiago Macieira 2018-09-19 00:05:54 -05:00
parent 3eebadc173
commit b7887f9b4f
2 changed files with 9 additions and 43 deletions

View File

@ -75,9 +75,14 @@ QT_BEGIN_NAMESPACE
* - accept4 2.6.28 * - accept4 2.6.28
* - renameat2 3.16 QT_CONFIG(renameat2) * - renameat2 3.16 QT_CONFIG(renameat2)
* - getrandom 3.17 QT_CONFIG(getentropy) * - getrandom 3.17 QT_CONFIG(getentropy)
* - statx 4.11 QT_CONFIG(statx)
*/ */
#if QT_CONFIG(getentropy) #if QT_CONFIG(statx)
# define MINLINUX_MAJOR 4
# define MINLINUX_MINOR 11
# define MINLINUX_PATCH 0
#elif QT_CONFIG(getentropy)
# define MINLINUX_MAJOR 3 # define MINLINUX_MAJOR 3
# define MINLINUX_MINOR 17 # define MINLINUX_MINOR 17
# define MINLINUX_PATCH 0 # define MINLINUX_PATCH 0

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2017 Intel Corporation. ** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch> ** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
@ -88,7 +88,6 @@ extern "C" NSString *NSTemporaryDirectory();
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include <sys/syscall.h>
# include <sys/sendfile.h> # include <sys/sendfile.h>
# include <linux/fs.h> # include <linux/fs.h>
@ -96,28 +95,6 @@ extern "C" NSString *NSTemporaryDirectory();
#ifndef FICLONE #ifndef FICLONE
# define FICLONE _IOW(0x94, 9, int) # define FICLONE _IOW(0x94, 9, int)
#endif #endif
# if defined(Q_OS_ANDROID)
// renameat2() and statx() are disabled on Android because quite a few systems
// come with sandboxes that kill applications that make system calls outside a
// whitelist and several Android vendors can't be bothered to update the list.
# undef SYS_renameat2
# undef SYS_statx
# undef STATX_BASIC_STATS
# else
# if !QT_CONFIG(renameat2) && defined(SYS_renameat2)
static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags)
{ return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); }
# endif
# if !QT_CONFIG(statx) && defined(SYS_statx)
# include <linux/stat.h>
static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf)
{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); }
# elif !QT_CONFIG(statx) && !defined(SYS_statx)
# undef STATX_BASIC_STATS
# endif
# endif // !Q_OS_ANDROID
#endif #endif
#ifndef STATX_ALL #ifndef STATX_ALL
@ -331,22 +308,8 @@ mtime(const T &statBuffer, int)
#ifdef STATX_BASIC_STATS #ifdef STATX_BASIC_STATS
static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer) static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer)
{ {
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
static QBasicAtomicInteger<qint8> statxTested = Q_BASIC_ATOMIC_INITIALIZER(0);
#else
static QBasicAtomicInt statxTested = Q_BASIC_ATOMIC_INITIALIZER(0);
#endif
if (statxTested.load() == -1)
return -ENOSYS;
unsigned mask = STATX_BASIC_STATS | STATX_BTIME; unsigned mask = STATX_BASIC_STATS | STATX_BTIME;
int ret = statx(fd, pathname, flags, mask, statxBuffer); int ret = statx(fd, pathname, flags, mask, statxBuffer);
if (ret == -1 && errno == ENOSYS) {
statxTested.store(-1);
return -ENOSYS;
}
statxTested.store(1);
return ret == -1 ? -errno : 0; return ret == -1 ? -errno : 0;
} }
@ -1282,14 +1245,12 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy
if (Q_UNLIKELY(srcPath.isEmpty() || tgtPath.isEmpty())) if (Q_UNLIKELY(srcPath.isEmpty() || tgtPath.isEmpty()))
return emptyFileEntryWarning(), false; return emptyFileEntryWarning(), false;
#if defined(RENAME_NOREPLACE) && (QT_CONFIG(renameat2) || defined(SYS_renameat2)) #if defined(RENAME_NOREPLACE) && QT_CONFIG(renameat2)
if (renameat2(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_NOREPLACE) == 0) if (renameat2(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_NOREPLACE) == 0)
return true; return true;
// If we're using syscall(), check for ENOSYS;
// if renameat2 came from libc, we don't accept ENOSYS.
// We can also get EINVAL for some non-local filesystems. // We can also get EINVAL for some non-local filesystems.
if ((QT_CONFIG(renameat2) || errno != ENOSYS) && errno != EINVAL) { if (errno != EINVAL) {
error = QSystemError(errno, QSystemError::StandardLibraryError); error = QSystemError(errno, QSystemError::StandardLibraryError);
return false; return false;
} }