summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
Commit message (Collapse)AuthorAgeFilesLines
...
* QStorageInfo/Linux: fix getting information on unmounted btrfs subvolsThiago Macieira2024-01-211-5/+23
| | | | | | | | | | | | | | | Amends 1cd6c6c69e9813c791f8bebb6c0c9214ce765060. Btrfs can have subvolumes and each one of them is assigned a device ID when the filesystem is loaded into the kernel. But subvolumes don't all have to be a mountpoint of their own: if we insist on matching device IDs, as initRootPath() was doing, we'd fail at finding the mount point. Fixes: QTBUG-121140 Pick-to: 6.7 Change-Id: I76ffba14ece04f24b43efffd17ab39f503000dd7 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QProcess/Doc: clarify that early crashes happen after started()Thiago Macieira2024-01-211-0/+6
| | | | | | | | | | | This is notable when dynamic linking fails, because that happens before the first line of main() (or equivalent) of the child process, so even banners printed by that function may be missing. Pick-to: 6.7 Change-Id: I5201966b308e48989c06fffd17aa9837156e23f4 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* QProcess/Doc: clarify that started() may be emitted very earlyThiago Macieira2024-01-211-12/+15
| | | | | | | | | | | | | | | | | | | | On Windows, process creation is synchronous so we will always emit either started() or errorOccurred() before QProcess::start() returns. This condition doesn't currently happen on Unix systems, but we could do that because we're now using vfork() on most platforms, so the child process has either successfully execve()d or _exit()ed before QProcessPrivate::startProcess continued. Drive-by reorganization of the code to remove the one-line \note in the middle of the docs. Pick-to: 6.5 6.6 6.7 Fixes: QTBUG-120968 Task-number: QTCREATORBUG-30066 Change-Id: I4d0668e0fae5299551ff91480828a68e62fdacec Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
* Doc: fix QStandardPaths::displayName qdoc warning on macOSVolker Hilsheimer2024-01-201-0/+2
| | | | | | | | | | | | | | | The function definition at the location of the documentation is not used on Q_OS_DARWIN, so qdoc cannot tie the documentation to it, leaving broken links and qdoc warnings when building the documentation on macOS. Fix this by explicitly specifying the function that's being documented. Pick-to: 6.7 Change-Id: Icf2ad1eba9e9ec8cbeea3818b414f740fa31083f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Safiyyah Moosa <safiyyah.moosa@qt.io>
* Add sys/types.h include to fix build with muslAndré Klitzing2024-01-152-1/+4
| | | | | | | | | This amends c82ed8b2795cbf6d82dfe3857fec7c16688137a4. Pick-to: 6.7 Fixes: QTBUG-120766 Change-Id: I2584c62d35c6ee0a9c8687a476f7eab52bd52af2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDebug: add missing #include <optional>Marc Mutz2024-01-151-0/+1
| | | | | | | | | | Found in API review. Amends b7657ddccbe0a5ab1cdfc61ae6b7f0501dbfb24a. Pick-to: 6.7 Change-Id: Ibdab7f51be09036659475bd76af28e8692235b9c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QFileSystemEntry: store special index, -2, in a contexpr variableAhmad Samir2024-01-141-10/+14
| | | | | | | | It is used to indicate resolveFilePaht() should be called, making it a named variable makes the intention clearer. Change-Id: Ibf1c88b9dacc59775afdf76bab3a8c86a52d5c72 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QProcess/Unix: detect ASan and TSan dynamicallyThiago Macieira2024-01-141-5/+13
| | | | | | | | | Fixes: QTBUG-117533 Fixes: QTBUG-117954 Task-number: QTBUG-104493 Pick-to: 6.7 6.6 Change-Id: I09c3950e719e4b259bc7fffd1793ee472c5d5a9a Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QDirIterator: manage fs/file iterators with unique_ptrAhmad Samir2024-01-141-24/+31
| | | | | | | | Use std::stack/std::vector, since QList doesn't work with move only types. Change-Id: If0009c8127d56f85bb6b4b7bd40251cdc6b7950d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirIteratorPrivate: assign to members directlyAhmad Samir2024-01-141-19/+34
| | | | | | | | | | | Instead of passing default args to the constructor. The alternative is adding as many constructors as the public class has. The dirEntry member benefits from copy-elision in the 3 QDirIterator overloads that construct a QFileSystemEntry. Change-Id: I7b6bcc54a7e00255be9903d58cc09f4e202a25c3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QFileSystem{Model,Watcher}: port to PMF signal/slot syntaxAhmad Samir2024-01-133-39/+30
| | | | | | | | | | | Also remove the `_q_` prefix from private slot names, it was needed to mark them as being used with Q_PRIVATE_SLOT, which is also gone in this commit. Drive-by change: de-duplicate some code. Change-Id: Ib41d0ac24ae584746751c0c2b5c477f600627db1 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
* QUrlQuery/Doc: fix resulting query with ( and ) delimitersThiago Macieira2024-01-121-2/+2
| | | | | | | | There's no final ) because there's nothing there to be delimited. Pick-to: 6.5 6.6 6.7 Change-Id: I6e2677aad2ab45759db2fffd17a4ce4aa902e140 Reviewed-by: David Faure <david.faure@kdab.com>
* QDataStream & QResource: document their lack of security-hardeningThiago Macieira2023-12-211-0/+13
| | | | | | | | | Pick-to: 6.7 6.6 6.5 Fixes: QTBUG-120012 Task-number: QTBUG-119178 Change-Id: I6e2677aad2ab45759db2fffd17a06af730e320d6 Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Doc: Fix documentation issues for Qt CoreTopi Reinio2023-12-192-9/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix template arguments in \fn signatures for Qt::compareThreeWay() functions. * Fix template arguments in \fn signatures for QDebug::operator<<() functions. * Fix \sa links to specific overloads of QSpan functions. * Fix \sa links to specific overloads of QFileInfo::fileTime(). * Remove references to 'Custom Type Example' (example has been removed). * Fix linking to 'JSON Save Game' example. * Fix references to 'Queued Custom Type' example. * Fix linking to QCryptographicHash::Algorithm. * Fix linking to Qt Qml module. * Fix undocumented parameters in qHypot(). Pick-to: 6.7 Change-Id: If9eb9978a14e147f003672a682972b319454c311 Reviewed-by: Luca Di Sera <luca.disera@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Move the settingseditor example into tests/manualVolker Hilsheimer2023-12-151-5/+1
| | | | | | | | | | | | | | | | The example uses QTreeWidget when it should use a QTreeView with a dedicated item model, primarily shows how to use item views (and very little about QSettings), and is generally not useful to show how an application could or should use QSettings to store settings. Turn it into a manual test instead; it's useful for that as it supports ini and plist files, and settings in different scopes. Pick-to: 6.7 Fixes: QTBUG-119978 Change-Id: I7ce039f6391c41c679d126d90a251eee60327c39 Reviewed-by: Ed Cooke <ed.cooke@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Long live QDebug::operator<<(q(u)int128)!Marc Mutz2023-12-092-0/+117
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Replace the ad-hoc implementation of QTest::toString() in tst_qglobal.cpp with a QDebug stream operator, so the QTest::toString() fall-back to QDebug::toString() kicks in. Since the ABI issues revolving around the new int128 types are not known, yet, avoid baking the types into the ABI by a) making the operators constrained templates¹ and b) passing though void* to the exported helpers. These functions return an error message if Qt was compiled without support for int128. Use the Thiago Trick™ (leaving obviouly dead code around for the compiler to remove without warning) to expose more code to more compilers. This appears to work elsewhere in Qt, so I hope it does here, too. This completes the minimum qint128 support so we're able to debug code and write tests that use these types. ¹ Templates, unlike inline member functions of wholly-exported classes, never² become part of the ABI. ² <insert here the convoluted scenario under which this is false> Fixes: QTBUG-117011 Change-Id: Ia4e56d26c6ffd18b7d69a7ceaed65b2211d258b2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QUrlQuery: drop the qpair.h includeMarc Mutz2023-12-081-1/+0
| | | | | | | | [ChangeLog][QtCore][Potentially Source-Incompatible Changes] qurlquery.h no longer includes qpair.h (for qMakePair). Change-Id: I593ca3fee5f330992b46170bb660b1b33a663428 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QUrlQuery: s/QPair/std::pair/Marc Mutz2023-12-072-18/+18
| | | | | | | | | | | | | | They're literally the same, QPair is an alias for std::pair, so this is both SC and BC. Also port from qMakePair to std::make_pair, so we can later drop the qpair.h include (not done here to avoid breaking 6.6/6.5 users relying on this transitive include for qMakePair(). Pick-to: 6.6 6.5 Change-Id: I593ca3fee5f330992b46170bb660b1b33a663427 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QDebug: remove QPair streaming docsMarc Mutz2023-12-072-11/+0
| | | | | | | | | QPair _is_ std::pair. If this wasn't a fake-definition under #ifdef Q_QDOC, the compiler would have complained long ago. Pick-to: 6.6 6.5 Change-Id: Idfe589ff13115d3d908572a17b849f634ec86787 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Create class documentation for QNtfsPermissionCheckGuardMate Barany2023-12-063-19/+102
| | | | | | | | | | ...and document the related functions as well. Pick-to: 6.6 Fixes: QTBUG-116350 Change-Id: I038d59f6af46b29e2123bc8b6c24ff4ffea78bbf Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Kai Köhne <kai.koehne@qt.io>
* Rename EINTR_LOOP -> QT_EINTR_LOOPMarc Mutz2023-11-305-7/+7
| | | | | | | | | | | | | | | This non-namespaced macro was defined in a header, and while that header is private, we shouldn't define non-namespaced macros in our headers. The macro also clashed with one of the same name defined in forkfd.c, which broke unity-builds including the forkfd_qt.cpp TU. This rename fixes that, too, so we can now remove forkfd_qt.cpp from NO_UNITY_BUILD_SOURCES. Pick-to: 6.6 6.5 Change-Id: Ic4bb4e4d7a632ca87905e48913db788a7c202314 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QStorageInfo/Linux: include linux/mount.h instead of sys/mount.hAhmad Samir2023-11-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | | Including <sys/mount.h> in qstorageinfo_linux.cpp broke -unity-build's in which qfilesystemengine_unix.cpp (which includes <linux/fs.h> which in turn includes <linux/mount.h>) ends up in the same unity_cxx_nn.cpp as qstorageinfo_linux.cpp. MS_RDONLY is a macro in one header and an enum in another, when both are in the same TU that's UB. This was fixed[1] upstream since glibc-2.36, but it's still an issue in Ubuntu 20.04, which has an older glibc IIUC. So, just inlcude <linux/mount.h> which works on Android too (according to precheck CI on gerrit). Amends b3eb951d18abfa48bb88b5039521d79103a6a322. [1] https://sourceware.org/glibc/wiki/Release/2.36#Usage_of_.3Clinux.2Fmount.h.3E_and_.3Csys.2Fmount.h.3E Task-number: QTBUG-119328 Change-Id: Ifa02272eea004051dd329b35f533385813215bfc Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* qDebug: add support for std::optional and std::nullopt_tDavid Faure2023-11-222-0/+28
| | | | | | | | | | [ChangeLog][QtCore][QDebug] Added support for std::optional and std::nullopt_t Change-Id: I1e6196adb408401cae8776cd0c60af294a39a83f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QProcess: work around GCC 13 -Wmaybe-uninitialized in -unity-buildMarc Mutz2023-11-191-1/+2
| | | | | | | | | | | | | | | When in a unity-build GCC 13 sees the implementation of forkfd_wait4(), called dfrom forkfd_wait(), it can prove that there are paths that do not initialize *info: Those paths are the returns following fcntl() in system_forkfs_wait() in forkd_linux.c and read() in forkfd_wait4(). To work around the issue and unbreak unity-builds, initialize info = {}. Task-number: QTBUG-119081 Pick-to: 6.6 6.5 Change-Id: I1b3504e7f83c766ebccc851233d4c3e677bf2acd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QStorageInfo/Linux: switch the non-Android version to also use statfs()Thiago Macieira2023-11-171-28/+5
| | | | | | | | | | | | | | | | It's the actual system call on Linux, inspired by the 4.4BSD call of the same name (and our BSD code also uses statfs(), except for NetBSD, but it probably could use statfs() there too). statvfs() wasn't introduced until POSIX.1-2001, though glibc added it in 1998 for version 2.1 and Bionic only for NDK version 19 in 2019. So we could merge the Android code to the POSIX version, but it's easier to merge the non-Android code to the raw system call. Change-Id: I8f3ce163ccc5408cac39fffd178dbd83567a78d5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QStorageInfo: change private blockSize member to intThiago Macieira2023-11-174-4/+4
| | | | | | | | | | | | It's what the public API returns. There's little reason to use ulong, despite that being the type that struct statvfs uses (on Windows, that was 32-bit anyway). Saves 8 bytes on the size of the QStorageInfoPrivate class. Change-Id: I8f3ce163ccc5408cac39fffd178db8cfb9e5e4f6 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Don't reuse iterator var to avoid -D_GLIBCXX_DEBUG crashMichael Weghorn2023-11-141-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For a CXXFLAGS='-D_GLIBCXX_DEBUG' build, running the examples/corelib/ipc/sharedmemory/sharedmemory example and clicking on the "Load Image from File..." button would result in a crash: > usr/include/c++/13/debug/safe_iterator.h:492: > In function: > bool gnu_debug::operator!=(const > _Safe_iterator<std::_Rb_tree_const_iterator<std::pair<const > QSettingsKey, QVariant> >, std::debug::map<QSettingsKey, QVariant, > std::less<QSettingsKey>, std::allocator<std::pair<const QSettingsKey, > QVariant> > >, std::forward_iterator_tag>::_Self&, const > _Safe_iterator<std::_Rb_tree_const_iterator<std::pair<const > QSettingsKey, QVariant> >, std::debug::map<QSettingsKey, QVariant, > std::less<QSettingsKey>, std::allocator<std::pair<const QSettingsKey, > QVariant> > >, std::forward_iterator_tag>::_Self&) > > Error: attempt to compare a singular iterator to a > singular (value-initialized) iterator. > > Objects involved in the operation: > iterator "lhs" @ 0x7ffe8e811550 { > type = std::_Rb_tree_const_iterator<std::pair<QSettingsKey const, QVariant> > (constant iterator); > state = singular; > } > iterator "rhs" @ 0x7ffe8e811670 { > type = std::_Rb_tree_const_iterator<std::pair<QSettingsKey const, QVariant> > (constant iterator); > state = singular (value-initialized); > } > Aborted (core dumped) This may be a libstdc++ bug, but still avoid/work around the issue by just using two separate variables for the iterators here. While at it, simplify the code a bit and replace the use of const_cast and pointers with the use of const references. Many thanks to Giuseppe D'Angelo for the analysis of the underlying problem and reporting a bug for GCC/libstdc++ [1] ! [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112477 Fixes: QTBUG-119044 Pick-to: 6.6 6.5 Change-Id: I00a8cc35033cf3ab4ba1f071cccabdef8ef52f9c Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* QStorageInfoPrivate/Linux: de-duplicate some codeAhmad Samir2023-11-042-9/+14
| | | | | | Change-Id: Ie0fe0c80a61c123c12242f24830ca622a726d7ac Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QProcess/Unix: also ban vfork() under TSanThiago Macieira2023-11-021-0/+4
| | | | | | | | | | | | | Complements 94ec17436cbdab52ed85e15ea197b538541b14ca for the ASan logic (52ed6af5277100ed5b9a4f4231b94013ce539a2c for the code change). Fixes: QTBUG-117533 Pick-to: 6.6 Change-Id: I09c3950e719e4b259bc7fffd1793d59dbdbfe82a Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Jonas Karlsson <jonas.karlsson@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* qurlidna: port some internal functions to QSVAnton Kudryavtsev2023-11-011-4/+4
| | | | | | Change-Id: If9c0090589cd58738165f2fe71701dba6958575c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* moveToTrash/Unix: use linkat() to check early for cross-device renamesThiago Macieira2023-10-261-55/+85
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This ensures that we will succeed in renaming files, because we already have created a link to it in the right directory. With this, we can remove the home filesystem check that was using QStorageInfo. The majority of file deletions we expect applications to perform will use this code path. An additional benefit is that we ensure we can't get an ENOSPC when renaming any more, because we already have the entry in the directory. This needs a fallback to the existing mechanism for two cases: * trashing full directories, because you can't hardlink them * when operating on a volume that isn't a Unix filesystem (e.g., a FAT filesystem on a removable device) QTemporaryFileName required a small change to allow non-absolute paths. openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 5 newfstatat(5, "", {st_mode=S_IFDIR|0700, st_size=18, ...}, AT_EMPTY_PATH) = 0 getuid() = 1000 openat(5, "files", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 6 linkat(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.MuahmK", 6, ".eRPdPI", 0) = 0 openat(5, "info", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 7 close(5) = 0 openat(7, "tst_qfile.moveToTrashOpenFile.MuahmK.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 5 [../etc/localtime..] write(5, "[Trash Info]\nPath=/home/tjmaciei"..., 103) = 103 renameat(6, ".eRPdPI", 6, "tst_qfile.moveToTrashOpenFile.MuahmK") = 0 unlink("/home/tjmaciei/tst_qfile.moveToTrashOpenFile.MuahmK") = 0 close(5) = 0 close(6) = 0 close(7) = 0 Change-Id: I9d43e5b91eb142d6945cfffd1786d714fc24f161 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QTemporaryFile(Name): don't make the path absolute on generationThiago Macieira2023-10-261-3/+2
| | | | | | | | | | | | | | | | | | I need to use QTemporaryFileName in a context where absolute paths are not allowed because they change the behavior of the system call (the -at() POSIX system calls); see next commit. This required a fix to a seemingly unrelated test, which depended on the absolute path, because QPluginLoader and QLibrary assume a file name with no path components imply "search the standard places". [ChangeLog][Important Behavior Changes][QTemporaryFile] This class will now return relative file paths in fileName() if the file template was also a relative path (it used to always return an absolute path). The temporary files are still created in the same directory; this change only affects the length of the path the function returns. Change-Id: I79e700614d034281bf55fffd178f65f2b3d602d8 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* qcore_unix: port qt_safe_poll to QDeadlineTimerAhmad Samir2023-10-241-3/+3
| | | | | | | | | | | | | | | | | | | | | | Remove qt_poll_msecs() since the "forever" state can be simply expressed with a QDeadlineTimer::Forever arg, instead of passing a nullptr timespec, and the negative timeouts treated as "run forever" is also encapsulated by QDealineTimer. Use the QDealineTimer(qint64) constructor in the call sites where the timeout could be negative, so that it creates a Forever timer (the QDeadlineTimer(chrono::duration) constructor uses setRemainingTime(duration) which handles negative timeouts by creating expired timers). Remove qt_gettime() (and do_gettime()). Drive-by changes: - Fix a narrowing conversion warning, qt_make_pollfd() takes an int - Remove an unused include Change-Id: I096319af5e191e28c3d39295fb1aafe9d69841e6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QStorageInfo/Unix: exclude invalid volumes from mountedVolumes()Thiago Macieira2023-10-212-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Invalid are usually those mounted on a filesystem we can't access: $ df /run/user/0/gvfs df: /run/user/0/gvfs: Permission denied $ ./qstorageinfo /run/user/0/gvfs Could not get info on /run/user/0/gvfs df already doesn't include it by default: $ df | grep -c gvfs 0 But we were: $./qstorageinfo | sed -n '1p;/gvfs/p' Filesystem (Type) Size Available BSize Label Mounted on gvfsd-fuse (fuse.gvfsd-fuse) RW 0 0 0 /run/user/0/gvfs Note also how this is showing a total size of 0, which is usually the type of filesystem we exclude. It's actually -1 but got rounded down to 0 when we divided by 1024. Pick-to: 6.6 Change-Id: I8f3ce163ccc5408cac39fffd178d7e4f9dc13b24 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QStorageInfo/Linux: decode the names encoded by udev in-placeThiago Macieira2023-10-211-18/+31
| | | | | | | | | | | | This function is only called with the name of a file coming from QFileInfo::fileName() so it's usually already detached anyway. And if there's nothing to decode, pass the string through without even attempting to modify it. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd1787651437074d35 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* QStorageInfo/Linux: avoid parsing /dev/disks/by-label for every entryThiago Macieira2023-10-211-4/+40
| | | | | | | | | | Instead, create a (flat) map of the entries that we can seek on while creating the list of mountedVolumes(). On my machine, that went down from 14 times to 1. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd17875458541f28f9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QStorageInfo/Linux: rewrite the label retriever to use device IDsThiago Macieira2023-10-212-18/+55
| | | | | | | | | | | | | | | | | | | | | | | Instead of the previous realpath() comparison resulting from the symlink processing. parseMountInfo() was extracting the device number from /proc, so this information was already readily available. We must take care of anonymous block devices (major == 0). Certain filesystems, such as btrfs, always use them, so we must still stat() the device path to get the real block device. This implementation assumes that udev only creates entries in the /dev/disks/by-label directory that are symlinks to real devices, but that must already be the case because they are in /dev in the first place. An alternative implementation would be to compare the inode and host device (st_dev) of the entry, if different /dev entries could have different labels. I don't think that's possible. But multiple /dev entries for the same device is definitely possible. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd1787552af3d09676 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QStorageInfo/Linux: fix mountedVolumes() for paths mounted overThiago Macieira2023-10-211-0/+2
| | | | | | | | | | | | | | | | | | | | This fixes a similar problem as the previous commit. Because Linux allows one to mount over non-empty paths, it's possible to make mountpoints unreachable, and yet they will still be present in the /proc/self/mountinfo listing. Because we have the device ID from the scan, we can confirm that the mountpoint matches the MountInfo. # mkdir -p /tmp/foo/bar # mount -t tmpfs /tmp/foo/bar # mount -t tmpfs -o size=1M /tmp/foo # mkdir /tmp/foo/bar $ ./tests/manual/qstorageinfo/qstorageinfo | awk 'NR==1 || /tmp\/foo/' Filesystem (Type) Size Available BSize Label Mounted on tmpfs RW 1024 1024 4096 /tmp/foo Change-Id: I79e700614d034281bf55fffd178f8b99b10a8b69 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QStorageInfo/Linux: fix setPath() for paths mounted overThiago Macieira2023-10-211-18/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Linux allows admins to mount new filesystems over non-empty paths (though I managed to do so on FreeBSD and macOS too), so we must find the most recent mount that applies to this path instead of the longest matching mountpoint. We do that by scanning the /proc/self/mountinfo list backwards and thus any matching isParentOf() must be the correct one. # mkdir -p /tmp/foo/bar # mount -t tmpfs tmpfs /tmp/foo/bar # mount -t tmpfs -o size=1M tmpfs /tmp/foo $ ./tests/manual/qstorageinfo/qstorageinfo /tmp/foo/bar Filesystem (Type) Size Available BSize Label Mounted on tmpfs RW 1024 1024 4096 /tmp/foo But we must guard against an earlier mount still being (somehow) accessible. We've seen this in the CI, where /run is earlier than / but still somehow accessible -- I guess this is one or a pair of mount --move. An additional benefit is that don't even attempt to compare to the virtual filesystems mounted by the system early after boot, if what we're looking for isn't the root. See next commit for a fix for QStorageInfo::mountedVolumes(). Change-Id: I79e700614d034281bf55fffd178f8befc5e80edb Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QFSFileEngine: minor code clarificationAhmad Samir2023-10-211-1/+2
| | | | | | Change-Id: I44f30f827cdb8e841a43ac911327286db051a725 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QSystemError: pass errno when calling stdString()Ahmad Samir2023-10-211-11/+12
| | | | | | | | | | | | | | | | | | errno should be queried immediately after a libc function call fails, calling it later on in QSystemError::stdString() may be too late. Part of the goal of this, and similar, changes is removing the default value of the stdString() method's parameter, to signify to users of that method that errno should be stored ASAP if there is an error. If there is any intervening code that may call a system/libc function store errno in a local int var, otherwise use it directly in the QSystemError::stdString() call, which takes by value. Task-number: QTBUG-115199 Change-Id: If3f601a023ed0014e260089771220668dad88be8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QIODevice: mark checkWarnMessage() as Q_DECL_COLD_FUNCTIONMarc Mutz2023-10-191-0/+1
| | | | | | | | | | | | | | | | | It's only called in exceptional circumstances, so the compiler should optimize it for size, not speed, and paths leading up to calls to this functions should be automatically marked as [[unlikely]]. Marking the function as cold accomplishes both. GCC 11 seems to have had this figured out by itself, possibly backtracking from the unconditional qWarning() in the first line of the function, but it did have a (very small) effect on Clang 15, so leave it in, if only as documentation. Pick-to: 6.6 6.5 6.2 Change-Id: Ie8e9049300825a3aae2f9678a2907ceea0b21d1c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Make WASM IDB settings use the fallback mechanism correctlyMikolaj Boc2023-10-182-20/+29
| | | | | Change-Id: Ibb65efc0faa5ec6e6c60782747c9295e4fc5ff21 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Simplify QWasmIDBSettingsPrivateMikolaj Boc2023-10-181-46/+7
| | | | | | | | | | Since QWasmIDBSettingsPrivate is only supported on JSPI now, there is no need to maintain the isReadReady flag anymore. This lets us simplify the class a lot. Change-Id: I67322389463af13b5110091a4f8433f08da19925 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* moveToTrash/Unix: refactor to use openat()/mkdirat()/renameat()Thiago Macieira2023-10-171-79/+128
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This ensures much better security against race conditions and attacks, at the expense of a few more system calls. On first run (when no trash dir is yet present): openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory) mkdirat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash", 0700) = 0 openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 5 newfstatat(5, "", {st_mode=S_IFDIR|0700, st_size=0, ...}, AT_EMPTY_PATH) = 0 getuid() = 1000 openat(5, "files", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory) mkdirat(5, "files", 0700) = 0 openat(5, "files", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 6 openat(5, "info", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory) mkdirat(5, "info", 0700) = 0 openat(5, "info", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 7 close(5) = 0 openat(7, "tst_qfile.moveToTrashOpenFile.fjYRxv.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 5 openat(AT_FDCWD, "/usr/share/zoneinfo/UTC", O_RDONLY|O_CLOEXEC) = 8 newfstatat(8, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0 newfstatat(8, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0 read(8, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 114 lseek(8, -60, SEEK_CUR) = 54 read(8, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 60 close(8) = 0 write(5, "[Trash Info]\nPath=/home/tjmaciei"..., 103) = 103 renameat(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.fjYRxv", 6, "tst_qfile.moveToTrashOpenFile.fjYRxv") = 0 close(5) = 0 close(6) = 0 close(7) = 0 On subsequent runs: openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 5 newfstatat(5, "", {st_mode=S_IFDIR|0700, st_size=18, ...}, AT_EMPTY_PATH) = 0 getuid() = 1000 openat(5, "files", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 6 openat(5, "info", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 7 close(5) = 0 openat(7, "tst_qfile.moveToTrashOpenFile.sPjrcA.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 5 openat(AT_FDCWD, "/usr/share/zoneinfo/UTC", O_RDONLY|O_CLOEXEC) = 8 newfstatat(8, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0 newfstatat(8, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0 read(8, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 114 lseek(8, -60, SEEK_CUR) = 54 read(8, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 60 close(8) = 0 write(5, "[Trash Info]\nPath=/home/tjmaciei"..., 103) = 103 renameat(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.sPjrcA", 6, "tst_qfile.moveToTrashOpenFile.sPjrcA") = 0 close(5) = 0 close(6) = 0 close(7) = 0 Change-Id: I9d43e5b91eb142d6945cfffd1787117927650dab Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* moveToTrash/Unix: use the file's inode number as collision avoidanceThiago Macieira2023-10-171-4/+15
| | | | | | | | | | | | | | | | | | | | | | | | Instead of a sequential and thus predictable counter. This improves the performance of when you keep creating and trashing the same file base name. The previous algorithm would try all occurrences from 0 to however many trashings have happened. This could have been any random number, but the source file's inode is "random" enough for us. strace of the second file's trashing: openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/info/tst_qfile.moveToTrashOpenFile.vLwfNe.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = -1 EEXIST (File exists) newfstatat(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.vLwfNe", {st_mode=S_IFREG|0644, st_size=16, ...}, 0) = 0 openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/info/tst_qfile.moveToTrashOpenFile.vLwfNe-23527891.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 4 newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=2852, ...}, 0) = 0 write(4, "[Trash Info]\nPath=/home/tjmaciei"..., 103) = 103 renameat2(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.vLwfNe", AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/files/tst_qfile.moveToTrashOpenFile.vLwfNe-23527891", RENAME_NOREPLACE) = 0 close(4) = 0 Change-Id: I9d43e5b91eb142d6945cfffd1786d73459c2eb3d Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* moveToTrash/Unix: use lower-level API to write the info fileThiago Macieira2023-10-171-33/+78
| | | | | | | | | | | | | | | | | | | | | | | | So we can more easily get any errors from attempting to write the file. It is possible to get them with QFile, by either doing .flush() or using QIODevice::Unbuffered, but using the C API is a definite sure way. Plus, since this is QFileSystemEngine, this avoids the possibility that QFile may choose to use a different file engine than the native one, for some reason. And it reduces overhead. This allows us to more easily detect why the file creation failed and therefore stop looping if the error wasn't EEXIST. That will avoid an infinite loop in case the necessary directories exist but aren't writable. It's also moved above the renaming, such that the failure to populate the info file prevents the renaming too. Both operations can have the same likely errors, ENOSPC and EIO. The likelihood of EIO is very low, for both; but for ENOSPC it's far more likely for writing the file. Avoiding the ENOSPC error for the renaming is handled in a later commit. Change-Id: I9d43e5b91eb142d6945cfffd1786d417142ac728 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* moveToTrash/Unix: avoid creating too many QStorageInfoThiago Macieira2023-10-171-19/+33
| | | | | | | | | | | | | | | | QStorageInfo is great, but rather expensive, so this introduces a faster check by stat()ing the source file and $HOME, to see if they are the same device, saving us two or three QStorageInfo constructions. That is a necessary condition: if they aren't the same device, we know rename() into $HOME/.local/share/Trash will fail. But it's not a sufficient condition: they need to be the same mount point and that's something only QStorageInfo will give us. Strictly speaking, the only way to be sure that you can rename() into the trash path is to, well, attempt it (as usual, something for a later commit). Change-Id: I9d43e5b91eb142d6945cfffd1786c474cac25083 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* moveToTrash/Unix: avoid TOCTOU in creating the unique file nameThiago Macieira2023-10-171-11/+6
| | | | | | | | | | This is not a security issue because we still use QIODevice::NewOnly (O_EXCL) and loop again. But because we do so, we don't need to check for existence with QFile::exists() in the first place. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd1786c98a39781517 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* moveToTrash/Unix: trust freeDesktopTrashLocation() to find the directoryThiago Macieira2023-10-171-14/+20
| | | | | | | | | | | | Make it receive the QSystemError so it can set the error condition properly in case the suitable location for this input file can't be found. This also includes the case when the input file does not exist in the first place, which I moved into the function because upcoming commits will imply this check anyway. Change-Id: I9d43e5b91eb142d6945cfffd1786c6e59d3b0204 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>