Changeset View
Changeset View
Standalone View
Standalone View
src/ioslaves/file/file.cpp
Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Line(s) | |||||
74 | #if HAVE_VOLMGT | 74 | #if HAVE_VOLMGT | ||
75 | #include <volmgt.h> | 75 | #include <volmgt.h> | ||
76 | #include <sys/mnttab.h> | 76 | #include <sys/mnttab.h> | ||
77 | #endif | 77 | #endif | ||
78 | 78 | | |||
79 | #include <kdirnotify.h> | 79 | #include <kdirnotify.h> | ||
80 | #include <ioslave_defaults.h> | 80 | #include <ioslave_defaults.h> | ||
81 | 81 | | |||
82 | #include "statjob.h" | ||||
83 | | ||||
82 | Q_LOGGING_CATEGORY(KIO_FILE, "kf5.kio.kio_file") | 84 | Q_LOGGING_CATEGORY(KIO_FILE, "kf5.kio.kio_file") | ||
83 | 85 | | |||
84 | // Pseudo plugin class to embed meta data | 86 | // Pseudo plugin class to embed meta data | ||
85 | class KIOPluginForMetaData : public QObject | 87 | class KIOPluginForMetaData : public QObject | ||
86 | { | 88 | { | ||
87 | Q_OBJECT | 89 | Q_OBJECT | ||
88 | Q_PLUGIN_METADATA(IID "org.kde.kio.slave.file" FILE "file.json") | 90 | Q_PLUGIN_METADATA(IID "org.kde.kio.slave.file" FILE "file.json") | ||
89 | }; | 91 | }; | ||
▲ Show 20 Lines • Show All 792 Lines • ▼ Show 20 Line(s) | |||||
882 | inline static uid_t stat_uid(QT_STATBUF &buf) { return buf.st_uid; } | 884 | inline static uid_t stat_uid(QT_STATBUF &buf) { return buf.st_uid; } | ||
883 | inline static gid_t stat_gid(QT_STATBUF &buf) { return buf.st_gid; } | 885 | inline static gid_t stat_gid(QT_STATBUF &buf) { return buf.st_gid; } | ||
884 | #endif | 886 | #endif | ||
885 | inline static time_t stat_atime(QT_STATBUF &buf) { return buf.st_atime; } | 887 | inline static time_t stat_atime(QT_STATBUF &buf) { return buf.st_atime; } | ||
886 | inline static time_t stat_mtime(QT_STATBUF &buf) { return buf.st_mtime; } | 888 | inline static time_t stat_mtime(QT_STATBUF &buf) { return buf.st_mtime; } | ||
887 | #endif | 889 | #endif | ||
888 | 890 | | |||
889 | bool FileProtocol::createUDSEntry(const QString &filename, const QByteArray &path, UDSEntry &entry, | 891 | bool FileProtocol::createUDSEntry(const QString &filename, const QByteArray &path, UDSEntry &entry, | ||
890 | short int details) | 892 | KIO::StatJob::StatDetails details) | ||
891 | { | 893 | { | ||
892 | assert(entry.count() == 0); // by contract :-) | 894 | assert(entry.count() == 0); // by contract :-) | ||
893 | switch (details) { | 895 | short entries = 0; | ||
894 | case 0: | 896 | if (details.testFlag(KIO::StatJob::Basic)) { | ||
dfaure: int is actually faster on most CPUs, and reserve() will convert it to an int anyway, so it… | |||||
Did you know you can just write if (details & KIO::StatJob::Basic)? Or did you use testFlag() for a specific reason? dfaure: Did you know you can just write `if (details & KIO::StatJob::Basic)`?
This is more C++-like… | |||||
I used testFlag because i was documented, and I still have to familiar myself with C/C++. meven: I used testFlag because i was documented, and I still have to familiar myself with C/C++. | |||||
895 | // filename, access, type, size, linkdest | 897 | // filename, access, type, size, linkdest | ||
896 | entry.reserve(5); | 898 | entries += 5; | ||
897 | break; | 899 | } | ||
898 | case 1: | 900 | if (details.testFlag(KIO::StatJob::User)) { | ||
899 | // uid, gid, atime, mtime, btime | 901 | // uid, gid | ||
900 | entry.reserve(10); | 902 | entries += 2; | ||
901 | break; | 903 | } | ||
902 | case 2: | 904 | if (details.testFlag(KIO::StatJob::Time)) { | ||
905 | // atime, mtime, btime | ||||
906 | entries += 3; | ||||
907 | } | ||||
908 | if (details.testFlag(KIO::StatJob::Acl)) { | ||||
903 | // acl data | 909 | // acl data | ||
904 | entry.reserve(13); | 910 | entries += 3; | ||
905 | break; | 911 | } | ||
906 | default: // case details > 2 | 912 | if (details.testFlag(KIO::StatJob::Inode)) { | ||
907 | // dev, inode | 913 | // dev, inode | ||
908 | entry.reserve(15); | 914 | entries += 2; | ||
909 | break; | | |||
910 | } | 915 | } | ||
916 | entry.reserve(entries); | ||||
917 | | ||||
918 | if (details.testFlag(KIO::StatJob::Basic)) { | ||||
911 | entry.fastInsert(KIO::UDSEntry::UDS_NAME, filename); | 919 | entry.fastInsert(KIO::UDSEntry::UDS_NAME, filename); | ||
920 | } | ||||
912 | 921 | | |||
913 | mode_t type; | 922 | mode_t type; | ||
914 | mode_t access; | 923 | mode_t access; | ||
915 | bool isBrokenSymLink = false; | 924 | bool isBrokenSymLink = false; | ||
916 | signed long long size = 0LL; | 925 | signed long long size = 0LL; | ||
917 | #if HAVE_POSIX_ACL | 926 | #if HAVE_POSIX_ACL | ||
918 | QByteArray targetPath = path; | 927 | QByteArray targetPath = path; | ||
919 | #endif | 928 | #endif | ||
920 | 929 | | |||
921 | #if HAVE_STATX | 930 | #if HAVE_STATX | ||
922 | // statx syscall is available | 931 | // statx syscall is available | ||
923 | struct statx buff; | 932 | struct statx buff; | ||
924 | #else | 933 | #else | ||
925 | QT_STATBUF buff; | 934 | QT_STATBUF buff; | ||
926 | #endif | 935 | #endif | ||
927 | 936 | | |||
928 | if (LSTAT(path.data(), &buff) == 0) { | 937 | if (LSTAT(path.data(), &buff) == 0) { | ||
929 | 938 | | |||
930 | if (details > 2) { | 939 | if (details.testFlag(KIO::StatJob::Inode)) { | ||
931 | entry.fastInsert(KIO::UDSEntry::UDS_DEVICE_ID, stat_dev(buff)); | 940 | entry.fastInsert(KIO::UDSEntry::UDS_DEVICE_ID, stat_dev(buff)); | ||
932 | entry.fastInsert(KIO::UDSEntry::UDS_INODE, stat_ino(buff)); | 941 | entry.fastInsert(KIO::UDSEntry::UDS_INODE, stat_ino(buff)); | ||
933 | } | 942 | } | ||
934 | 943 | | |||
935 | if ((stat_mode(buff) & QT_STAT_MASK) == QT_STAT_LNK) { | 944 | if ((stat_mode(buff) & QT_STAT_MASK) == QT_STAT_LNK) { | ||
936 | 945 | | |||
946 | if (details.testFlag(KIO::StatJob::Basic)) { | ||||
937 | #ifdef Q_OS_WIN | 947 | #ifdef Q_OS_WIN | ||
938 | const QString linkTarget = QFile::symLinkTarget(QFile::decodeName(path)); | 948 | const QString linkTarget = QFile::symLinkTarget(QFile::decodeName(path)); | ||
939 | #else | 949 | #else | ||
940 | // Use readlink on Unix because symLinkTarget turns relative targets into absolute (#352927) | 950 | // Use readlink on Unix because symLinkTarget turns relative targets into absolute (#352927) | ||
941 | #if HAVE_STATX | 951 | #if HAVE_STATX | ||
942 | size_t lowerBound = 256; | 952 | size_t lowerBound = 256; | ||
943 | size_t higherBound = 1024; | 953 | size_t higherBound = 1024; | ||
944 | uint64_t s = stat_size(buff); | 954 | uint64_t s = stat_size(buff); | ||
Show All 24 Lines | 975 | } else if (n > 0 && static_cast<SizeType>(n) != bufferSize) { | |||
969 | break; | 979 | break; | ||
970 | } | 980 | } | ||
971 | bufferSize *= 2; | 981 | bufferSize *= 2; | ||
972 | linkTargetBuffer.resize(bufferSize); | 982 | linkTargetBuffer.resize(bufferSize); | ||
973 | } | 983 | } | ||
974 | const QString linkTarget = QFile::decodeName(linkTargetBuffer); | 984 | const QString linkTarget = QFile::decodeName(linkTargetBuffer); | ||
975 | #endif | 985 | #endif | ||
976 | entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, linkTarget); | 986 | entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, linkTarget); | ||
987 | } | ||||
977 | 988 | | |||
978 | // A symlink -> follow it only if details>1 | 989 | // A symlink -> follow it only if details>1 | ||
979 | if (details > 1) { | 990 | if (details.testFlag(KIO::StatJob::ResolveSymlink)) { | ||
980 | if (STAT(path.constData(), &buff) == -1) { | 991 | if (STAT(path.constData(), &buff) == -1) { | ||
981 | isBrokenSymLink = true; | 992 | isBrokenSymLink = true; | ||
982 | } else { | 993 | } else { | ||
983 | #if HAVE_POSIX_ACL | 994 | #if HAVE_POSIX_ACL | ||
995 | if (details.testFlag(KIO::StatJob::Acl)) { | ||||
984 | // valid symlink, will get the ACLs of the destination | 996 | // valid symlink, will get the ACLs of the destination | ||
985 | targetPath = linkTargetBuffer; | 997 | targetPath = linkTargetBuffer; | ||
998 | } | ||||
986 | #endif | 999 | #endif | ||
987 | } | 1000 | } | ||
988 | } | 1001 | } | ||
989 | } | 1002 | } | ||
990 | } else { | 1003 | } else { | ||
991 | // qCWarning(KIO_FILE) << "lstat didn't work on " << path.data(); | 1004 | // qCWarning(KIO_FILE) << "lstat didn't work on " << path.data(); | ||
992 | return false; | 1005 | return false; | ||
993 | } | 1006 | } | ||
994 | 1007 | | |||
1008 | if (details.testFlag(KIO::StatJob::Basic)) { | ||||
995 | if (isBrokenSymLink) { | 1009 | if (isBrokenSymLink) { | ||
996 | // It is a link pointing to nowhere | 1010 | // It is a link pointing to nowhere | ||
997 | type = S_IFMT - 1; | 1011 | type = S_IFMT - 1; | ||
998 | access = S_IRWXU | S_IRWXG | S_IRWXO; | 1012 | access = S_IRWXU | S_IRWXG | S_IRWXO; | ||
999 | size = 0LL; | 1013 | size = 0LL; | ||
1000 | } else { | 1014 | } else { | ||
1001 | type = stat_mode(buff) & S_IFMT; // extract file type | 1015 | type = stat_mode(buff) & S_IFMT; // extract file type | ||
1002 | access = stat_mode(buff) & 07777; // extract permissions | 1016 | access = stat_mode(buff) & 07777; // extract permissions | ||
1003 | size = stat_size(buff); | 1017 | size = stat_size(buff); | ||
1004 | } | 1018 | } | ||
1005 | 1019 | | |||
1006 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, type); | 1020 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, type); | ||
1007 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, access); | 1021 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, access); | ||
1008 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, size); | 1022 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, size); | ||
1023 | } | ||||
1009 | 1024 | | |||
1010 | #if HAVE_POSIX_ACL | 1025 | #if HAVE_POSIX_ACL | ||
1011 | if (details > 1) { | 1026 | if (details.testFlag(KIO::StatJob::Acl)) { | ||
1012 | /* Append an atom indicating whether the file has extended acl information | 1027 | /* Append an atom indicating whether the file has extended acl information | ||
1013 | * and if withACL is specified also one with the acl itself. If it's a directory | 1028 | * and if withACL is specified also one with the acl itself. If it's a directory | ||
1014 | * and it has a default ACL, also append that. */ | 1029 | * and it has a default ACL, also append that. */ | ||
1015 | appendACLAtoms(targetPath, entry, type); | 1030 | appendACLAtoms(targetPath, entry, type); | ||
1016 | } | 1031 | } | ||
1017 | #endif | 1032 | #endif | ||
1018 | 1033 | | |||
1019 | if (details > 0) { | 1034 | if (details.testFlag(KIO::StatJob::User)) { | ||
1020 | entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, stat_mtime(buff)); | | |||
1021 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, stat_atime(buff)); | | |||
1022 | #ifndef Q_OS_WIN | 1035 | #ifndef Q_OS_WIN | ||
1023 | entry.fastInsert(KIO::UDSEntry::UDS_USER, getUserName(KUserId(stat_uid(buff)))); | 1036 | entry.fastInsert(KIO::UDSEntry::UDS_USER, getUserName(KUserId(stat_uid(buff)))); | ||
1024 | entry.fastInsert(KIO::UDSEntry::UDS_GROUP, getGroupName(KGroupId(stat_gid(buff)))); | 1037 | entry.fastInsert(KIO::UDSEntry::UDS_GROUP, getGroupName(KGroupId(stat_gid(buff)))); | ||
1025 | #else | 1038 | #else | ||
1026 | #pragma message("TODO: st_uid and st_gid are always zero, use GetSecurityInfo to find the owner") | 1039 | #pragma message("TODO: st_uid and st_gid are always zero, use GetSecurityInfo to find the owner") | ||
1027 | #endif | 1040 | #endif | ||
1041 | } | ||||
1042 | | ||||
1043 | if (details.testFlag(KIO::StatJob::Time)) { | ||||
1044 | entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, stat_mtime(buff)); | ||||
1045 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, stat_atime(buff)); | ||||
1028 | 1046 | | |||
1029 | #ifdef st_birthtime | 1047 | #ifdef st_birthtime | ||
1030 | /* For example FreeBSD's and NetBSD's stat contains a field for | 1048 | /* For example FreeBSD's and NetBSD's stat contains a field for | ||
1031 | * the inode birth time: st_birthtime | 1049 | * the inode birth time: st_birthtime | ||
1032 | * This however only works on UFS and ZFS, and not, on say, NFS. | 1050 | * This however only works on UFS and ZFS, and not, on say, NFS. | ||
1033 | * Instead of setting a bogus fallback like st_mtime, only use | 1051 | * Instead of setting a bogus fallback like st_mtime, only use | ||
1034 | * it if it is greater than 0. */ | 1052 | * it if it is greater than 0. */ | ||
1035 | if (buff.st_birthtime > 0) { | 1053 | if (buff.st_birthtime > 0) { | ||
▲ Show 20 Lines • Show All 522 Lines • Show Last 20 Lines |
int is actually faster on most CPUs, and reserve() will convert it to an int anyway, so it might as well be an int from the beginning.