static __inline int gettype(struct nftw *state, struct dirent64 *dp, struct stat64 *st) { struct dirent_extra_stat *extra; int embed; for (embed = 0, extra = (struct dirent_extra_stat *)_DEXTRA_FIRST(dp); _DEXTRA_VALID(extra, dp); extra = (struct dirent_extra_stat *)_DEXTRA_NEXT(extra)) { if ((embed = ((extra->d_type == _DTYPE_STAT && !(state->flags & FTW_PHYS)) || (extra->d_type == _DTYPE_LSTAT && ((state->flags & FTW_PHYS) || !S_ISLNK(extra->d_stat.st_mode)))) != 0)) break; } if (embed) memcpy(st, &extra->d_stat, sizeof(struct stat64)); else if ((*state->statfn)(state->pathname, st) == -1) return((errno != EACCES && errno != ENOENT) ? -1 : (!(state->flags & FTW_PHYS) && (*state->lstatfn)(state->pathname, st) == 0 && S_ISLNK(st->st_mode)) ? FTW_SLN : FTW_NS); return(S_ISDIR(st->st_mode) ? FTW_D : S_ISLNK(st->st_mode) ? FTW_SL : FTW_F); }
void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) { #if defined(Q_OS_QNX) knownFlagsMask = 0; entryFlags = 0; for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); extra = _DEXTRA_NEXT(extra)) { if (extra->d_type == _DTYPE_STAT || extra->d_type == _DTYPE_LSTAT) { const struct dirent_extra_stat * const extra_stat = reinterpret_cast<struct dirent_extra_stat *>(extra); // Remember whether this was a link or not, this saves an lstat() call later. if (extra->d_type == _DTYPE_LSTAT) { knownFlagsMask |= QFileSystemMetaData::LinkType; if (S_ISLNK(extra_stat->d_stat.st_mode)) entryFlags |= QFileSystemMetaData::LinkType; } // For symlinks, the extra type _DTYPE_LSTAT doesn't work for filling out the meta data, // as we need the stat() information there, not the lstat() information. // In this case, don't use the extra information. // Unfortunately, readdir() never seems to return extra info of type _DTYPE_STAT, so for // symlinks, we always incur the cost of an extra stat() call later. if (S_ISLNK(extra_stat->d_stat.st_mode) && extra->d_type == _DTYPE_LSTAT) continue; #if defined(QT_USE_XOPEN_LFS_EXTENSIONS) && defined(QT_LARGEFILE_SUPPORT) // Even with large file support, d_stat is always of type struct stat, not struct stat64, // so it needs to be converted struct stat64 statBuf; fillStat64fromStat32(&statBuf, extra_stat->d_stat); fillFromStatBuf(statBuf); #else fillFromStatBuf(extra_stat->d_stat); #endif knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; if (!S_ISLNK(extra_stat->d_stat.st_mode)) { knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; entryFlags |= QFileSystemMetaData::ExistsAttribute; } } } #elif defined(_DIRENT_HAVE_D_TYPE) || defined(Q_OS_BSD4) // BSD4 includes Mac OS X // ### This will clear all entry flags and knownFlagsMask switch (entry.d_type) { case DT_DIR: knownFlagsMask = QFileSystemMetaData::LinkType | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType | QFileSystemMetaData::SequentialType | QFileSystemMetaData::ExistsAttribute; entryFlags = QFileSystemMetaData::DirectoryType | QFileSystemMetaData::ExistsAttribute; break; case DT_BLK: case DT_CHR: case DT_FIFO: case DT_SOCK: // ### System attribute knownFlagsMask = QFileSystemMetaData::LinkType | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType | QFileSystemMetaData::BundleType | QFileSystemMetaData::AliasType | QFileSystemMetaData::SequentialType | QFileSystemMetaData::ExistsAttribute; entryFlags = QFileSystemMetaData::SequentialType | QFileSystemMetaData::ExistsAttribute; break; case DT_LNK: knownFlagsMask = QFileSystemMetaData::LinkType; entryFlags = QFileSystemMetaData::LinkType; break; case DT_REG: knownFlagsMask = QFileSystemMetaData::LinkType | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType | QFileSystemMetaData::BundleType | QFileSystemMetaData::SequentialType | QFileSystemMetaData::ExistsAttribute; entryFlags = QFileSystemMetaData::FileType | QFileSystemMetaData::ExistsAttribute; break; case DT_UNKNOWN: default: clear(); } #else Q_UNUSED(entry) #endif }