Stop using readdir_r: glibc deprecated it and it's not a good idea
POSIX does not require that readdir() be reentrant even for operations on different dirent objects, but all implementations (according to the glibc documentation) already do that. Moreover, it's not a good idea to use readdir_r since the buffer space is limited by the caller, so certain file names may be too long (ENAMETOOLONG) -- we had a workaround for QNX, but for no other OS. According to the glibc documentation, it is expected that POSIX will mark readdir_r obsolete and instead require some form of reentrancy for readdir. This commit makes everyone use readdir instead. The macros in qplatformdefs.h are left behind in case someone else is using them. With glibc 2.24, we started getting: qplatformdefs.h:150:35: warning: ‘int readdir_r(DIR*, dirent*, dirent**)’ is deprecated [-Wdeprecated-declarations] qfilesystemiterator_unix.cpp:112:17: note: in expansion of macro ‘QT_READDIR_R’ Task-number: QTBUG-56088 Change-Id: I33dc971f005a4848bb8ffffd14749b4082f62e69 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: James McDonnell <jmcdonnell@blackberry.com>
This commit is contained in:
parent
cf4e7575ca
commit
4b6784b49c
@ -216,7 +216,7 @@ bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(QT_EXT_QNX_READDIR_R)
|
||||
#if defined(_DEXTRA_FIRST)
|
||||
static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32)
|
||||
{
|
||||
statBuf64->st_mode = statBuf32.st_mode;
|
||||
@ -281,7 +281,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer)
|
||||
|
||||
void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry)
|
||||
{
|
||||
#if defined(QT_EXT_QNX_READDIR_R)
|
||||
#if defined(_DEXTRA_FIRST)
|
||||
knownFlagsMask = 0;
|
||||
entryFlags = 0;
|
||||
for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry);
|
||||
|
@ -87,14 +87,6 @@ private:
|
||||
#else
|
||||
QT_DIR *dir;
|
||||
QT_DIRENT *dirEntry;
|
||||
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R)
|
||||
// for readdir_r
|
||||
QScopedPointer<QT_DIRENT, QScopedPointerPodDeleter> mt_file;
|
||||
#if defined(QT_EXT_QNX_READDIR_R)
|
||||
// for _readdir_r
|
||||
size_t direntSize;
|
||||
#endif
|
||||
#endif
|
||||
int lastError;
|
||||
#endif
|
||||
|
||||
|
@ -46,9 +46,6 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
|
||||
: nativePath(entry.nativeFilePath())
|
||||
, dir(0)
|
||||
, dirEntry(0)
|
||||
#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
|
||||
, direntSize(0)
|
||||
#endif
|
||||
, lastError(0)
|
||||
{
|
||||
Q_UNUSED(filters)
|
||||
@ -58,32 +55,8 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
|
||||
if ((dir = QT_OPENDIR(nativePath.constData())) == 0) {
|
||||
lastError = errno;
|
||||
} else {
|
||||
|
||||
if (!nativePath.endsWith('/'))
|
||||
nativePath.append('/');
|
||||
|
||||
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R)
|
||||
// ### Race condition; we should use fpathconf and dirfd().
|
||||
size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX);
|
||||
if (maxPathName == size_t(-1))
|
||||
maxPathName = FILENAME_MAX;
|
||||
maxPathName += sizeof(QT_DIRENT) + 1;
|
||||
|
||||
QT_DIRENT *p = reinterpret_cast<QT_DIRENT*>(::malloc(maxPathName));
|
||||
Q_CHECK_PTR(p);
|
||||
|
||||
mt_file.reset(p);
|
||||
#if defined(QT_EXT_QNX_READDIR_R)
|
||||
direntSize = maxPathName;
|
||||
|
||||
// Include extra stat information in the readdir() call (d_stat member of
|
||||
// dirent_extra_stat). This is used in QFileSystemMetaData::fillFromDirEnt() to
|
||||
// avoid extra stat() calls when iterating over directories
|
||||
int flags = dircntl(dir, D_GETFLAG) | D_FLAG_STAT | D_FLAG_FILTER;
|
||||
if (dircntl(dir, D_SETFLAG, flags) == -1)
|
||||
lastError = errno;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,18 +71,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
|
||||
if (!dir)
|
||||
return false;
|
||||
|
||||
#if defined(QT_EXT_QNX_READDIR_R)
|
||||
lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize);
|
||||
if (lastError)
|
||||
return false;
|
||||
#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
|
||||
lastError = QT_READDIR_R(dir, mt_file.data(), &dirEntry);
|
||||
if (lastError)
|
||||
return false;
|
||||
#else
|
||||
// ### add local lock to prevent breaking reentrancy
|
||||
dirEntry = QT_READDIR(dir);
|
||||
#endif // _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
|
||||
if (dirEntry) {
|
||||
fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath());
|
||||
|
Loading…
x
Reference in New Issue
Block a user