127bool QFSFileEnginePrivate::nativeSyncToDisk()
131#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
132 QT_EINTR_LOOP(ret, fdatasync(nativeHandle()));
134 QT_EINTR_LOOP(ret, fsync(nativeHandle()));
137 q->setError(QFile::WriteError, qt_error_string(errno));
144qint64 QFSFileEnginePrivate::nativeRead(
char *data, qint64 len)
148 if (fh && nativeIsSequential()) {
149 size_t readBytes = 0;
150 int oldFlags = fcntl(QT_FILENO(fh), F_GETFL);
151 for (
int i = 0; i < 2; ++i) {
153 if ((oldFlags & O_NONBLOCK) == 0)
154 fcntl(QT_FILENO(fh), F_SETFL, oldFlags | O_NONBLOCK);
159 read = fread(data + readBytes, 1, size_t(len - readBytes), fh);
160 }
while (read == 0 && !feof(fh) && errno == EINTR);
171 if ((oldFlags & O_NONBLOCK) == 0) {
172 fcntl(QT_FILENO(fh), F_SETFL, oldFlags);
173 if (readBytes == 0) {
176 readByte = fgetc(fh);
177 }
while (readByte == -1 && errno == EINTR);
178 if (readByte != -1) {
179 *data = uchar(readByte);
188 if ((oldFlags & O_NONBLOCK) == 0) {
189 fcntl(QT_FILENO(fh), F_SETFL, oldFlags);
191 if (readBytes == 0 && !feof(fh)) {
193 q->setError(QFile::ReadError, qt_error_string(errno));
199 return readFdFh(data, len);
279bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags)
const
281 if (!tried_stat || !metaData.hasFlags(flags)) {
285 if (fh && fileEntry.isEmpty())
286 localFd = QT_FILENO(fh);
288 QFileSystemEngine::fillMetaData(localFd, metaData);
290 if (metaData.missingFlags(flags) && !fileEntry.isEmpty())
291 QFileSystemEngine::fillMetaData(fileEntry, metaData, metaData.missingFlags(flags));
294 return metaData.exists();
308QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type)
const
310 Q_D(
const QFSFileEngine);
315 QAbstractFileEngine::FileFlags ret = { };
317 if (type & FlagsMask)
318 ret |= LocalDiskFlag;
322 QFileSystemMetaData::MetaDataFlags queryFlags = { };
324 queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type.toInt()))
325 & QFileSystemMetaData::Permissions;
327 if (type & TypesMask)
328 queryFlags |= QFileSystemMetaData::AliasType
329 | QFileSystemMetaData::LinkType
330 | QFileSystemMetaData::FileType
331 | QFileSystemMetaData::DirectoryType
332 | QFileSystemMetaData::BundleType
333 | QFileSystemMetaData::WasDeletedAttribute;
335 if (type & FlagsMask)
336 queryFlags |= QFileSystemMetaData::HiddenAttribute
337 | QFileSystemMetaData::ExistsAttribute;
338 else if (type & ExistsFlag)
339 queryFlags |= QFileSystemMetaData::WasDeletedAttribute;
341 queryFlags |= QFileSystemMetaData::LinkType;
343 exists = d->doStat(queryFlags);
346 if (!exists && !d->metaData.isLink())
349 if (exists && (type & PermsMask))
350 ret |= FileFlags(uint(d->metaData.permissions().toInt()));
352 if (type & TypesMask) {
353 if (d->metaData.isAlias()) {
356 if ((type & LinkType) && d->metaData.isLink())
359 if (d->metaData.isFile()) {
361 }
else if (d->metaData.isDirectory()) {
362 ret |= DirectoryType;
363 if ((type & BundleType) && d->metaData.isBundle())
370 if (type & FlagsMask) {
372 if (!d->metaData.wasDeleted())
374 if (d->fileEntry.isRoot())
376 else if (d->metaData.isHidden())
391QString QFSFileEngine::fileName(FileName file)
const
393 Q_D(
const QFSFileEngine);
396 return QFileSystemEngine::bundleName(d->fileEntry);
398 return d->fileEntry.fileName();
400 return d->fileEntry.path();
402 case AbsolutePathName: {
403 QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry));
404 return file == AbsolutePathName ? entry.path() : entry.filePath();
407 case CanonicalPathName: {
408 QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry, d->metaData));
409 return file == CanonicalPathName ? entry.path() : entry.filePath();
411 case AbsoluteLinkTarget:
412 if (d->isSymlink()) {
413 QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData);
414 return entry.filePath();
418 if (d->isSymlink()) {
419 QFileSystemEntry entry = QFileSystemEngine::getRawLinkPath(d->fileEntry, d->metaData);
420 return entry.filePath();
429 return d->fileEntry.filePath();
457bool QFSFileEngine::setPermissions(uint perms)
464 d->metaData.clearFlags(QFileSystemMetaData::Permissions);
467 ok = QFileSystemEngine::setPermissions(d->fd, QFile::Permissions(perms), error);
469 ok = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error);
471 setError(QFile::PermissionsError, error.toString());
477bool QFSFileEngine::setSize(qint64 size)
482 ret = QT_FTRUNCATE(d->fd, size) == 0;
484 ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0;
486 ret = QT_TRUNCATE(d->fileEntry.nativeFilePath().constData(), size) == 0;
488 setError(QFile::ResizeError, qt_error_string(errno));
492bool QFSFileEngine::setFileTime(
const QDateTime &newDate, QFile::FileTime time)
496 if (d->openMode == QIODevice::NotOpen) {
497 setError(QFile::PermissionsError, qt_error_string(EACCES));
502 if (!QFileSystemEngine::setFileTime(d->nativeHandle(), newDate, time, error)) {
503 setError(QFile::PermissionsError, error.toString());
507 d->metaData.clearFlags(QFileSystemMetaData::Times);
511uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
513 qint64 maxFileOffset = std::numeric_limits<QT_OFF_T>::max();
514#if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
522 maxFileOffset = qMin((Q_INT64_C(1) << (32+12)) - 1, maxFileOffset);
526 if (openMode == QIODevice::NotOpen) {
527 q->setError(QFile::PermissionsError, qt_error_string(EACCES));
531 if (offset < 0 || offset > maxFileOffset
533 || quint64(size) > quint64(size_t(-1))) {
534 q->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
539 if (doStat(QFileSystemMetaData::SizeAttribute)
540 && (QT_OFF_T(size) > metaData.size() - QT_OFF_T(offset)))
541 qWarning(
"QFSFileEngine::map: Mapping a file beyond its size is not portable");
544 if (openMode & QIODevice::ReadOnly) access |= PROT_READ;
545 if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE;
547 int sharemode = MAP_SHARED;
548 if (flags & QFileDevice::MapPrivateOption) {
549 sharemode = MAP_PRIVATE;
550 access |= PROT_WRITE;
553#if defined(Q_OS_INTEGRITY)
554 int pageSize = sysconf(_SC_PAGESIZE);
556 int pageSize = getpagesize();
558 int extra = offset % pageSize;
560 if (quint64(size + extra) > quint64((size_t)-1)) {
561 q->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
565 size_t realSize = (size_t)size + extra;
566 QT_OFF_T realOffset = QT_OFF_T(offset);
567 realOffset &= ~(QT_OFF_T(pageSize - 1));
569 void *mapAddress = QT_MMAP((
void*)
nullptr, realSize,
570 access, sharemode, nativeHandle(), realOffset);
572 uchar *address = extra +
static_cast<uchar*>(mapAddress);
573 maps[address] = {extra, realSize};
579 q->setError(QFile::PermissionsError, qt_error_string(EACCES));
583 q->setError(QFile::ResourceError, qt_error_string(errno));
588 q->setError(QFile::UnspecifiedError, qt_error_string(errno));
594bool QFSFileEnginePrivate::unmap(uchar *ptr)
596#if !defined(Q_OS_INTEGRITY)
598 const auto it = std::as_const(maps).find(ptr);
599 if (it == maps.cend()) {
600 q->setError(QFile::PermissionsError, qt_error_string(EACCES));
604 uchar *start = ptr - it->start;
605 size_t len = it->length;
606 if (-1 == munmap(start, len)) {
607 q->setError(QFile::UnspecifiedError, qt_error_string(errno));
620QAbstractFileEngine::TriStateResult QFSFileEngine::cloneTo(QAbstractFileEngine *target)
623 if ((target->fileFlags(LocalDiskFlag) & LocalDiskFlag) == 0)
624 return TriStateResult::NotSupported;
626 int srcfd = d->nativeHandle();
627 int dstfd = target->handle();
628 TriStateResult r = QFileSystemEngine::cloneFile(srcfd, dstfd, d->metaData);
629 if (r == TriStateResult::Failed)
630 setError(QFile::CopyError, qt_error_string(errno));