diff --git a/autotests/jobtest.h b/autotests/jobtest.h --- a/autotests/jobtest.h +++ b/autotests/jobtest.h @@ -85,6 +85,7 @@ void stat(); void statDetailsBasic(); void statDetailsBasicSetDetails(); + void statDetailsWithInode(); #ifndef Q_OS_WIN void statSymlink(); #endif diff --git a/autotests/jobtest.cpp b/autotests/jobtest.cpp --- a/autotests/jobtest.cpp +++ b/autotests/jobtest.cpp @@ -1505,6 +1505,69 @@ QCOMPARE(kioItem.time(KFileItem::AccessTime), QDateTime()); } +void JobTest::statDetailsWithInode() +{ + const QString filePath = homeTmpDir() + "fileFromHome"; + createTestFile(filePath); + const QUrl url(QUrl::fromLocalFile(filePath)); + KIO::StatJob *job = KIO::statDetails(url, KIO::StatJob::SourceSide, KIO::StatDefaultDetails | KIO::StatInode); + QVERIFY(job); + QVERIFY2(job->exec(), qPrintable(job->errorString())); + // TODO set setSide + const KIO::UDSEntry &entry = job->statResult(); + + QVERIFY(entry.contains(KIO::UDSEntry::UDS_NAME)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_ACCESS)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_SIZE)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_FILE_TYPE)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_USER)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_GROUP)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_MODIFICATION_TIME)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_ACCESS_TIME)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_DEVICE_ID)); + QVERIFY(entry.contains(KIO::UDSEntry::UDS_INODE)); +#if 1 // should be #ifdef HAVE_STATX + QVERIFY(entry.contains(KIO::UDSEntry::UDS_CREATION_TIME)); + QCOMPARE(entry.count(), 11); +#else + QCOMPARE(entry.count(), 10); +#endif + + QVERIFY(!entry.isDir()); + QVERIFY(!entry.isLink()); + QCOMPARE(entry.stringValue(KIO::UDSEntry::UDS_NAME), QStringLiteral("fileFromHome")); + + // Compare what we get via kio_file and what we get when KFileItem stat()s directly + const KFileItem kioItem(entry, url); + const KFileItem fileItem(url); + QCOMPARE(kioItem.name(), fileItem.name()); + QCOMPARE(kioItem.url(), fileItem.url()); + QCOMPARE(kioItem.size(), fileItem.size()); + QCOMPARE(kioItem.user(), fileItem.user()); + QCOMPARE(kioItem.group(), fileItem.group()); + QCOMPARE(kioItem.mimetype(), fileItem.mimetype()); + QCOMPARE(kioItem.permissions(), fileItem.permissions()); + QCOMPARE(kioItem.time(KFileItem::ModificationTime), fileItem.time(KFileItem::ModificationTime)); + QCOMPARE(kioItem.time(KFileItem::AccessTime), fileItem.time(KFileItem::AccessTime)); + + // this part doesn't make sense on the CI as it's an LXC container with one partition + if (!otherTmpDirIsOnSamePartition()) { + const QString path = otherTmpDir() + "otherFile"; + createTestFile(path); + const QUrl otherUrl(QUrl::fromLocalFile(path)); + KIO::StatJob *otherJob = KIO::statDetails(otherUrl, KIO::StatJob::SourceSide, + KIO::StatDefaultDetails | KIO::StatInode); + QVERIFY(otherJob); + QVERIFY2(otherJob->exec(), qPrintable(otherJob->errorString())); + const KIO::UDSEntry otherEntry = otherJob->statResult(); + + const int device = entry.numberValue(KIO::UDSEntry::UDS_DEVICE_ID); + const int otherDevice = otherEntry.numberValue(KIO::UDSEntry::UDS_DEVICE_ID); + qDebug() << "device ID:" << device << "; otherDevice ID:" << otherDevice; + QVERIFY(device != otherDevice); + } +} + #ifndef Q_OS_WIN void JobTest::statSymlink() { diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp --- a/src/ioslaves/file/file_unix.cpp +++ b/src/ioslaves/file/file_unix.cpp @@ -53,6 +53,7 @@ #if HAVE_STATX #include +#include // for makedev() #endif //sendfile has different semantics in different platforms @@ -283,7 +284,7 @@ return statx(AT_FDCWD, path, AT_STATX_SYNC_AS_STAT, mask, buff); } inline static uint16_t stat_mode(struct statx &buf) { return buf.stx_mode; } -inline static uint32_t stat_dev(struct statx &buf) { return buf.stx_dev_major; } +inline static dev_t stat_dev(struct statx &buf) { return makedev(buf.stx_dev_major, buf.stx_dev_minor); } inline static uint64_t stat_ino(struct statx &buf) { return buf.stx_ino; } inline static uint64_t stat_size(struct statx &buf) { return buf.stx_size; } inline static uint32_t stat_uid(struct statx &buf) { return buf.stx_uid; }