Changeset View
Changeset View
Standalone View
Standalone View
src/ioslaves/file/file.cpp
Show First 20 Lines • Show All 71 Lines • ▼ Show 20 Line(s) | |||||
72 | #if HAVE_VOLMGT | 72 | #if HAVE_VOLMGT | ||
73 | #include <volmgt.h> | 73 | #include <volmgt.h> | ||
74 | #include <sys/mnttab.h> | 74 | #include <sys/mnttab.h> | ||
75 | #endif | 75 | #endif | ||
76 | 76 | | |||
77 | #include <kdirnotify.h> | 77 | #include <kdirnotify.h> | ||
78 | #include <ioslave_defaults.h> | 78 | #include <ioslave_defaults.h> | ||
79 | 79 | | |||
80 | #if HAVE_STATX | ||||
81 | // Since there's no glibc wrapper for statx() yet, we have to make the system call | ||||
82 | // by hand | ||||
83 | #include <fcntl.h> // AT_SYMLINK_NOFOLLOW constant comes from here | ||||
84 | #include <asm/unistd.h> | ||||
85 | #include <sys/syscall.h> | ||||
86 | // 332 on my system | ||||
dakon: This comment isn't needed either. | |||||
87 | #define STAT(path, buf) syscall(__NR_statx,(AT_FDCWD),(path),(AT_SYMLINK_NOFOLLOW),(0),(buf)) | ||||
88 | #else | ||||
89 | #define STAT(path, buf) QT_LSTAT(path, buf) | ||||
90 | #endif | ||||
91 | | ||||
80 | Q_LOGGING_CATEGORY(KIO_FILE, "kf5.kio.kio_file") | 92 | Q_LOGGING_CATEGORY(KIO_FILE, "kf5.kio.kio_file") | ||
81 | 93 | | |||
82 | // Pseudo plugin class to embed meta data | 94 | // Pseudo plugin class to embed meta data | ||
83 | class KIOPluginForMetaData : public QObject | 95 | class KIOPluginForMetaData : public QObject | ||
84 | { | 96 | { | ||
85 | Q_OBJECT | 97 | Q_OBJECT | ||
86 | Q_PLUGIN_METADATA(IID "org.kde.kio.slave.file" FILE "file.json") | 98 | Q_PLUGIN_METADATA(IID "org.kde.kio.slave.file" FILE "file.json") | ||
87 | }; | 99 | }; | ||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Line(s) | 245 | #endif | |||
259 | 271 | | |||
260 | finished(); | 272 | finished(); | ||
261 | } | 273 | } | ||
262 | 274 | | |||
263 | void FileProtocol::setModificationTime(const QUrl &url, const QDateTime &mtime) | 275 | void FileProtocol::setModificationTime(const QUrl &url, const QDateTime &mtime) | ||
264 | { | 276 | { | ||
265 | const QString path(url.toLocalFile()); | 277 | const QString path(url.toLocalFile()); | ||
266 | QT_STATBUF statbuf; | 278 | QT_STATBUF statbuf; | ||
267 | if (QT_LSTAT(QFile::encodeName(path).constData(), &statbuf) == 0) { | 279 | if (STAT(QFile::encodeName(path).constData(), &statbuf) == 0) { | ||
268 | struct utimbuf utbuf; | 280 | struct utimbuf utbuf; | ||
269 | utbuf.actime = statbuf.st_atime; // access time, unchanged | 281 | utbuf.actime = statbuf.st_atime; // access time, unchanged | ||
270 | utbuf.modtime = mtime.toTime_t(); // modification time | 282 | utbuf.modtime = mtime.toTime_t(); // modification time | ||
271 | if (::utime(QFile::encodeName(path).constData(), &utbuf) != 0) { | 283 | if (::utime(QFile::encodeName(path).constData(), &utbuf) != 0) { | ||
272 | if (auto err = execWithElevatedPrivilege(UTIME, {path, qint64(utbuf.actime), qint64(utbuf.modtime)}, errno)) { | 284 | if (auto err = execWithElevatedPrivilege(UTIME, {path, qint64(utbuf.actime), qint64(utbuf.modtime)}, errno)) { | ||
273 | if (!err.wasCanceled()) { | 285 | if (!err.wasCanceled()) { | ||
274 | // TODO: errno could be EACCES, EPERM, EROFS | 286 | // TODO: errno could be EACCES, EPERM, EROFS | ||
275 | error(KIO::ERR_CANNOT_SETTIME, path); | 287 | error(KIO::ERR_CANNOT_SETTIME, path); | ||
Show All 16 Lines | 299 | { | |||
292 | // Remove existing file or symlink, if requested (#151851) | 304 | // Remove existing file or symlink, if requested (#151851) | ||
293 | if (metaData(QStringLiteral("overwrite")) == QLatin1String("true")) { | 305 | if (metaData(QStringLiteral("overwrite")) == QLatin1String("true")) { | ||
294 | if (!QFile::remove(path)) { | 306 | if (!QFile::remove(path)) { | ||
295 | execWithElevatedPrivilege(DEL, {path}, errno); | 307 | execWithElevatedPrivilege(DEL, {path}, errno); | ||
296 | } | 308 | } | ||
297 | } | 309 | } | ||
298 | 310 | | |||
299 | QT_STATBUF buff; | 311 | QT_STATBUF buff; | ||
300 | if (QT_LSTAT(QFile::encodeName(path).constData(), &buff) == -1) { | 312 | if (STAT(QFile::encodeName(path).constData(), &buff) == -1) { | ||
301 | bool dirCreated = QDir().mkdir(path); | 313 | bool dirCreated = QDir().mkdir(path); | ||
302 | if (!dirCreated) { | 314 | if (!dirCreated) { | ||
303 | if (auto err = execWithElevatedPrivilege(MKDIR, {path}, errno)) { | 315 | if (auto err = execWithElevatedPrivilege(MKDIR, {path}, errno)) { | ||
304 | if (!err.wasCanceled()) { | 316 | if (!err.wasCanceled()) { | ||
305 | //TODO: add access denied & disk full (or another reasons) handling (into Qt, possibly) | 317 | //TODO: add access denied & disk full (or another reasons) handling (into Qt, possibly) | ||
306 | error(KIO::ERR_CANNOT_MKDIR, path); | 318 | error(KIO::ERR_CANNOT_MKDIR, path); | ||
307 | } | 319 | } | ||
308 | return; | 320 | return; | ||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Line(s) | 574 | { | |||
567 | 579 | | |||
568 | const QString dest_orig = url.toLocalFile(); | 580 | const QString dest_orig = url.toLocalFile(); | ||
569 | 581 | | |||
570 | // qDebug() << dest_orig << "mode=" << _mode; | 582 | // qDebug() << dest_orig << "mode=" << _mode; | ||
571 | 583 | | |||
572 | QString dest_part(dest_orig + QLatin1String(".part")); | 584 | QString dest_part(dest_orig + QLatin1String(".part")); | ||
573 | 585 | | |||
574 | QT_STATBUF buff_orig; | 586 | QT_STATBUF buff_orig; | ||
575 | const bool bOrigExists = (QT_LSTAT(QFile::encodeName(dest_orig).constData(), &buff_orig) != -1); | 587 | const bool bOrigExists = (STAT(QFile::encodeName(dest_orig).constData(), &buff_orig) != -1); | ||
576 | bool bPartExists = false; | 588 | bool bPartExists = false; | ||
577 | const bool bMarkPartial = config()->readEntry("MarkPartial", true); | 589 | const bool bMarkPartial = config()->readEntry("MarkPartial", true); | ||
578 | 590 | | |||
579 | if (bMarkPartial) { | 591 | if (bMarkPartial) { | ||
580 | QT_STATBUF buff_part; | 592 | QT_STATBUF buff_part; | ||
581 | bPartExists = (QT_LSTAT(QFile::encodeName(dest_part).constData(), &buff_part) != -1); | 593 | bPartExists = (STAT(QFile::encodeName(dest_part).constData(), &buff_part) != -1); | ||
582 | 594 | | |||
583 | if (bPartExists && !(_flags & KIO::Resume) && !(_flags & KIO::Overwrite) && buff_part.st_size > 0 && ((buff_part.st_mode & QT_STAT_MASK) == QT_STAT_REG)) { | 595 | if (bPartExists && !(_flags & KIO::Resume) && !(_flags & KIO::Overwrite) && buff_part.st_size > 0 && ((buff_part.st_mode & QT_STAT_MASK) == QT_STAT_REG)) { | ||
584 | // qDebug() << "calling canResume with" << KIO::number(buff_part.st_size); | 596 | // qDebug() << "calling canResume with" << KIO::number(buff_part.st_size); | ||
585 | 597 | | |||
586 | // Maybe we can use this partial file for resuming | 598 | // Maybe we can use this partial file for resuming | ||
587 | // Tell about the size we have, and the app will tell us | 599 | // Tell about the size we have, and the app will tell us | ||
588 | // if it's ok to resume or not. | 600 | // if it's ok to resume or not. | ||
589 | _flags |= canResume(buff_part.st_size) ? KIO::Resume : KIO::DefaultFlags; | 601 | _flags |= canResume(buff_part.st_size) ? KIO::Resume : KIO::DefaultFlags; | ||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Line(s) | 845 | { | |||
835 | entry.reserve(8); | 847 | entry.reserve(8); | ||
836 | 848 | | |||
837 | entry.insert(KIO::UDSEntry::UDS_NAME, filename); | 849 | entry.insert(KIO::UDSEntry::UDS_NAME, filename); | ||
838 | 850 | | |||
839 | mode_t type; | 851 | mode_t type; | ||
840 | mode_t access; | 852 | mode_t access; | ||
841 | QT_STATBUF buff; | 853 | QT_STATBUF buff; | ||
842 | 854 | | |||
843 | if (QT_LSTAT(path.data(), &buff) == 0) { | 855 | if (STAT(path.data(), &buff) == 0) { | ||
... but we fill buff using lstat(), not using QFile, so it doesn't matter what QFile does. dfaure: ... but we fill `buff` using `lstat()`, not using QFile, so it doesn't matter what QFile does. | |||||
844 | 856 | | |||
845 | if (details > 2) { | 857 | if (details > 2) { | ||
846 | entry.insert(KIO::UDSEntry::UDS_DEVICE_ID, buff.st_dev); | 858 | entry.insert(KIO::UDSEntry::UDS_DEVICE_ID, buff.st_dev); | ||
847 | entry.insert(KIO::UDSEntry::UDS_INODE, buff.st_ino); | 859 | entry.insert(KIO::UDSEntry::UDS_INODE, buff.st_ino); | ||
848 | } | 860 | } | ||
849 | 861 | | |||
850 | if ((buff.st_mode & QT_STAT_MASK) == QT_STAT_LNK) { | 862 | if ((buff.st_mode & QT_STAT_MASK) == QT_STAT_LNK) { | ||
851 | 863 | | |||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | 934 | #ifdef st_birthtime | |||
930 | } | 942 | } | ||
931 | #endif | 943 | #endif | ||
932 | #ifdef __st_birthtime | 944 | #ifdef __st_birthtime | ||
933 | /* As above, but OpenBSD calls it slightly differently. */ | 945 | /* As above, but OpenBSD calls it slightly differently. */ | ||
934 | if (buff.__st_birthtime > 0) { | 946 | if (buff.__st_birthtime > 0) { | ||
935 | entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, buff.__st_birthtime); | 947 | entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, buff.__st_birthtime); | ||
936 | } | 948 | } | ||
937 | #endif | 949 | #endif | ||
950 | #ifdef stx_btime | ||||
Where would that define come from? At least on glibc 2.28 I see it nowhere defined. dakon: Where would that define come from? At least on glibc 2.28 I see it nowhere defined. | |||||
951 | /* As above, but it's called "stx_btime" in Linux kernel 4.11+ | ||||
952 | * where statx() is available */ | ||||
953 | if (buff.stx_btime > 0) { | ||||
954 | entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, buff.stx_btime); | ||||
955 | } | ||||
956 | #endif | ||||
938 | } | 957 | } | ||
939 | 958 | | |||
940 | // Note: buff.st_ctime isn't the creation time ! | 959 | // Note: buff.st_ctime isn't the creation time ! | ||
941 | // We made that mistake for KDE 2.0, but it's in fact the | 960 | // We made that mistake for KDE 2.0, but it's in fact the | ||
942 | // "file status" change time, which we don't care about. | 961 | // "file status" change time, which we don't care about. | ||
943 | // For FreeBSD and NetBSD, use st_birthtime. For OpenBSD, | 962 | // For FreeBSD and NetBSD, use st_birthtime. For OpenBSD, | ||
944 | // use __st_birthtime. | 963 | // use __st_birthtime. | ||
945 | 964 | | |||
▲ Show 20 Lines • Show All 508 Lines • Show Last 20 Lines |
This comment isn't needed either.