summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
Commit message (Collapse)AuthorAgeFilesLines
* Add security scoped file engine for Apple operating systemsTor Arne Vestbø16 hours4-1/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On Apple operating systems where the app runs in a sandbox, the application can not access files outside of its sandbox without explicit user approval. This applies to iOS and friends, as well as optionally for macOS (when the sandbox is enabled, which is a requirement for publishing apps to the macOS App Store). When the user gives explicit access to a file or directory, we need to manage this access at runtime by starting and stopping the access via startAccessingSecurityScopedResource and stopAccessingSecurityScopedResource, and these functions must be balanced, to avoid leaking kernel resources. The access unfortunately doesn't persist automatically when the application terminates (unlike takePersistableUriPermission on Android), so we have to manually persist the access via security scoped bookmarks. We store these inside the app's own sandbox, in a way that limits the access to only that application, so persisting them on behalf of the user should be fine. The persisted bookmarks are loaded in the background on application start, ready for when the application wants to open earlier accessed file or directories. [ChangeLog][Apple] Sandboxed applications on Apple platforms, (including macOS if opted in to) can now access files outside of the application sandbox (so called security scoped resources) for both reading and writing. Files or folders chosen by the user via file dialogs or similar native mechanism are automatically and transparently handled, including persistent access across application and device restarts. Fixes: QTBUG-120528 Task-number: QTBUG-117832 Task-number: QTBUG-120528 Task-number: QTBUG-141414 Change-Id: I90d94066cbf7cd74750049d5d1b990917fd10cad Reviewed-by: Doris Verria <doris.verria@qt.io>
* Build with QT_NO_URL_CAST_FROM_STRINGAhmad Samir7 days1-0/+6
| | | | | | | | | | | Can't mark the whole repo with that macro, because in corelib that would take out the QString conversion operator which is BiC. Add a hard build-time error if QT_NO_URL_CAST_FROM_STRING is defined in corelib, as requested in code review. Change-Id: Ia0e302a2f82b86800e84d15e86ab138f78d45e4d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix QRandomAccessAsyncFile::close() logic on macOSIvan Solovev8 days2-23/+71
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The QRandomAccessAsyncFilePrivate::close() function is supposed to cancel all operations and close all the related IO channels, including the main IO channel. The initial implementation had a false assumption that the callback indicating that the main IO channel is closed is always the last callback that is called in this scenario. So, that callback was used to unconditionally call wakeOne() on the condition variable that was used to signal that all operations are completed. However, in practice when we cancel the operations, we receive the following callbacks: * close callback from each IO channel related to each operation; * completion callback for read/write operations with done set to true and error code indicating cancellation; * close callback from the main IO channel. All these callbacks can come in an arbitrary order. As a result, the case when multiple operations are still in progress, and the file is removed (or close() is called) was randomly crashing on CI, because the completion callbacks were trying to access the already-removed file. This patch updates the logic to only wake a condition variable when all callbacks are received. In order to do that we introduce a new m_numChannelsToClose variable to keep track of the number of active channels, and use the size of the m_runningOps set to track the running operations. To verify that the approach works reliably, I manually ran the equivalent of tst_QRandomAccessAsyncFile::fileRemovedInProgress() 100'000 times for each operation (owning and non-owning read/write separately). Amends e6b26ad1eca555ee1e6b2c4e9b4c7676dc754b04. Fixes: QTBUG-141730 Change-Id: I874b9b9999398f787b5039c78bc3d3eee44c088c Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Remove redundant Q_FLAGS usage from two private classesAhmad Samir11 days1-1/+0
| | | | | | | | | Both classes don't inherit from QObject, so the Q_FLAGS macro doesn't register anything with the meta-object system here. Task-number: QTBUG-99060 Change-Id: Id25f8b92cfe6eeade28059f5f7c661603f08e863 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Enable support for QFile::moveToTrash() on iOSTor Arne Vestbø12 days1-11/+0
| | | | | | | | | | | | The platform nowadays has support for moving files to the trash. Doing so will make the file available under "Recently Deleted" in the Files app. Pick-to: 6.10 Task-number: QTBUG-120528 Change-Id: I38d1115d96eb6df8512f0165db93af5c1c8b595b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QFileSystemEngine/Win: use qEnvironmentVariable instead of qgetenvMate Barany13 days1-5/+5
| | | | | | | | | It returns a QString immediately so there is no need for additional conversions. On Windows, it is also lossless. Pick-to: 6.10 Change-Id: I672d362116551a578c9eb111dd56785893de22be Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLockFile: call applicationPid() only onceThiago Macieira2025-11-011-2/+3
| | | | | | | | | | | | Our PID won't change between calls. The function is declared "const", but in LTO mode it got inlined and thus GCC emitted two calls to getpid(). Amends db1027bc360cb86526d95dd0d7f36107a4d36b47. Pick-to: 6.10 Change-Id: I7853e9db3d3b54745828fffda4053c13d3d257f9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QSaveFile: add std::filesystem::path supportThiago Macieira2025-10-282-0/+34
| | | | | | | Fixes: QTBUG-141433 Change-Id: I8fbc9a78026237e0e823fffd1760cff3adf0bd40 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QFile: move the std::filesystem supporting content to qfiledevice.hThiago Macieira2025-10-282-28/+33
| | | | | | | | So this can be used for QSaveFile. Change-Id: I9a5e12778acffe3382e1fffdad99da8ba440ad76 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QIOOperation: use std::get_if everywhereMårten Nordheim2025-10-281-6/+6
| | | | | | | std::get has code that uses exceptions. Change-Id: I9c2a46779bcf00ec9574432e7ca0383ce9288046 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QLockFile: add some missing std::move()sMarc Mutz2025-10-281-2/+2
| | | | | | | | | | | | | | | Coverity complained that two QByteArrays were copied into the LockFileInfo struct when a move was possible. It's correct. Add the moves. Amends 772863355a0cf57a49e93608790dfd17c8fd82da. Pick-to: 6.10 6.8 6.5 Coverity-Id: 896868 Coverity-Id: 896870 Change-Id: I146a588e4b2ef5bb6053274479ad96bcbdf75c11 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QSaveFile: merge the QString constructorsThiago Macieira2025-10-242-12/+3
| | | | | | | | Now that we don't need to keep the !QT_NO_QOBJECT code. Change-Id: Iad40e29375680befca7cfffdec7085a7f641c76f Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: BogDan Vatra <bogdan@kdab.com>
* QSaveFile: remove !QT_NO_QOBJECT supportThiago Macieira2025-10-242-15/+1
| | | | | | | | | | | Amends commit 670810787318df8a80b2197b49448c18a78bb7ed, which removed qsavefile.cpp from the bootstrap lib. Pick-to: 6.10 Change-Id: Iac520c557c978d6f9ec3fffd3dd83a18ca6a98df Reviewed-by: BogDan Vatra <bogdan@kdab.com> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QFileSystemEngine/Unix: work around copy_file_range() returning EINVALThiago Macieira2025-10-241-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | Looks like Linux does return EINVAL with ecryptfs. I didn't know anyone still used it, because there had been discussions in 2023 that it was deprecated and going stale on its crypto. > Hi - I don't think an additional reviewer is going to be sufficient to > get eCryptfs into a good state long term. There are fairly large > design problems that need more attention. I'll send a patch to > deprecate and mark for removal in 2025. The 2025 removal hasn't happened, though the discussion has reoccurred[2] with the subject "ecryptfs is unmaintained and untested". I suppose people who installed systems when Ubuntu recommended it may still have such systems around. [1] https://lore.kernel.org/lkml/20230403134432.46726-1-frank.li@vivo.com/T/#ecc899c0c24fbcb7ad0ed78301cf812dd33cc594b [2] https://lore.kernel.org/lkml/Zx-ndBo7wpYSHWPK@casper.infradead.org/ Pick-to: 6.10 6.8 Fixes: QTBUG-141371 Change-Id: I7a04c783b344e774d253fffd26474ffc012583c8 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Add macOS backend for QRandomAccessAsyncFileIvan Solovev2025-10-242-11/+829
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The backend uses Grand Central Dispatch to perform async IO. One complication is that the GCD APIs do not allow to cancel a signle IO read/write operation, instead it's only possilbe to close the related IO channel. Luckily, it's possible to have multiple IO channels referencing the same file descriptor. As a result, we end up duplicating IO channels for each async operation, which makes the code a bit more complicated. The implementation uses QWaitCondition to make sure that the async operation is completed or canceled before removing the relevant QIOOperation or QRandomAcessAsyncFile instance. Another tricky part was the implementation of flush(). The docs for dispatch_io_barrier claim that it applies to a file descriptor, not a specific channel, and thus acts as a barrier across all channels that share the same file descriptor. However, in practice it does not work! As a result, the patch implements an operation queue, and schedules the barrier operations only when all previous operations are completed. Similarly, no new operations are scheduled until the barrier operation is completed. The same logic is applied to the async open() operations that are also considered to be barrier operations. Fixes: QTBUG-139005 Change-Id: Iac448d9460c64dd18dc3b15fc13d5145895a3c3b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* QRAAFP: get rid of the QObjectPrivateVersion parameter in c-torIvan Solovev2025-10-212-3/+3
| | | | | | | | | | | The parameter is not really relevant for classes inside QtCore, as it's mostly used to bind a library to a certain version of QtCore if it relies on specific private APIs. Amends 65b7217ae71ad8b0448a0ba60e7e33350e84d97c. Change-Id: I167221eb1746cf36adde3da1fd11b4062cb77a0a Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QLockFile/win: Open the file with FILE_SHARE_DELETEMårten Nordheim2025-10-201-4/+24
| | | | | | | | | So we may be able to switch to using SetFileInformationByHandle to perform the deletion without closing the HANDLE first some time in the future. Task-number: QTBUG-140486 Change-Id: I8098d7f54e00e20065310e29436eb8e29bea60ae Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLockFile: refactor local helper into static member functionsMårten Nordheim2025-10-204-18/+34
| | | | | | | | | | | | | To prepare for the Windows backend doing extra work. We want to open the file with FILE_SHARE_DELETE so that we can eventually create the file with the DELETE permission, enabling us to delete it without closing the handle first. Since we can't do that through QFile directly we need to open the file descriptor first and then pass that to QFile. Change-Id: I0baf0ee3089b489f3bd1e0259cc06195e9256647 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix crash when trying to register .rcc from resource systemJoni Poikelin2025-10-091-3/+3
| | | | | | | | | | | | _get_osfhandle crashes if invalid value is passed in as a file descriptor. Avoid trying to map if there is no valid file descriptor for a file. Fixes: QTBUG-138807 Pick-to: 6.10 6.8 Change-Id: I462b93d3665c1894fb966080d106839b9840a05b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* (QtCore) doc: Add alt text for \image tagsEren Bursali2025-10-092-8/+13
| | | | | | | | | Adding alt texts that were needed for QDoc QTBUG-135118 Change-Id: Ie1b1cee06342803907b2c3d3bfd88191e3f175d8 Reviewed-by: Kai Köhne <kai.koehne@qt.io>
* corelib: fix clang narrowing conversion warnings -Wshorten-64-to-32Ahmad Samir2025-10-062-2/+4
| | | | | | | | | | | | | | qlogging.cpp: ::backtrace() takes an int. QLoggingSettingsParser: fgets() takes an int. QFileSystemEntry: filePath() would never exceed PATH_MAX on Unix; and on windows even with the extended long path option it should fit in an int: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation Pick-to: 6.10 6.8 6.5 Change-Id: I288f4adc71740e077ed0c11de4e38f6fddc00455 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QFSFileEngine: remove unused open() overloadsThiago Macieira2025-09-202-12/+0
| | | | | | | | | | These two-arg open() functions aren't used anywhere. I couldn't find the last obvious use of either, so gave up doing further searches as unnecessary work. Pick-to: 6.10 6.9 6.8 Change-Id: Ie02540f8ed968591d009fffd6bbf11b568f6916f Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QLockFile: inline getLockFileHandle() so it's not in the QtCore DLLThiago Macieira2025-09-202-13/+5
| | | | | | | | | | It's only used by the unit test, so we shouldn't need it in regular builds. In doing that, we can also fix the file descriptor leak on Windows. Pick-to: 6.10 Change-Id: I38f87e4acc15167f8284fffdf8d76f09242aa787 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Move all Q_DECL_(PURE|CONST)_FUNCTION markers to the frontMårten Nordheim2025-09-192-2/+2
| | | | | | | | | While testing defining Q_DECL_PURE_FUNCTION for MSVC I discovered it cannot handle having the marker trailing, while GCC/clang can cope with either. Change-Id: Ic9dd088996c191263e2f2a43c2f6a16533bdb9c5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLockFile/Win: replace DeleteFile with CreateFile w/o sharingThiago Macieira2025-09-181-1/+19
| | | | | | | | | | | | | | | | | | | What looks like an antithetical change actually makes sense: we open the file with FILE_FLAG_DELETE_ON_CLOSE, which causes the file to be deleted when we CloseHandle(). In fact, this is exactly how wine implements DeleteFile[1]. The difference between this and DeleteFile itself is that we are opening the file for writing but not allowing any sharing. This means no other process in the system can open the file at the same time as we do, even if they want to cooperate in deleting it. [1] https://github.com/wine-mirror/wine/blob/wine-10.15/dlls/kernelbase/file.c#L1011 Fixes: QTBUG-140053 Pick-to: 6.10 6.9 6.8 Change-Id: Iba265eba236f496ce5c9fffdc5daf95d5f429358 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QLockFile: bypass QFile::remove() and go straight to the system callThiago Macieira2025-09-182-12/+25
| | | | | | | | | | | | | This then avoids creating a QFilePrivate, QFSFileEngine, and QFSFileEnginePrivate only to call QFileSystemEngine::removeFile(). We are definitely using native files in this class, so we can skip all of those classes. We use the system call in removeStaleLock() anyway for Unix. Pick-to: 6.10 6.9 6.8 Change-Id: I19ea637567ae38d31888fffd61ec79ae3eec50af Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Make QRandomAccessAsyncFile::open() an async operationIvan Solovev2025-09-185-20/+103
| | | | | | | | | | | | | | | | The tricky case now would be to handle the case when the user tries to call open() several times. Make sure that after the first operation is started, all the subsequent attempts to open will fail until the first operation is finished. Obviously, if the first open() was successful, the file needs to be closed before it can be re-opened. Add unit-tests to cover these cases. Also add some tests for close() corner cases. These tests are useful for this commit, as the logic of opening the file got more complicated. Task-number: QTBUG-136763 Change-Id: Id505e6278fbc1d523a52b54e69ba896a3d754762 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Extend tests for QRandomAccessAsyncFileIvan Solovev2025-09-181-0/+5
| | | | | | | | | | | | | | | Add tests that check read/write operations with empty buffers. For owning read also test a case when a negative maxSize is provided. The latter revealed that the code was not handling negative maxSize properly. So, add a warning and reset it to zero in such case. The value of zero does not have any special meaning, and would simply result into the operation emitting finished() immediately. Task-number: QTBUG-136763 Change-Id: I72232a788ce2a18188f76d50db00b09b1af57169 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add QRandomAccessAsyncFile::flush() methodIvan Solovev2025-09-185-17/+107
| | | | | | | | | | | | | | The flush() operation would normally return bool, indicating if it was successful or not. As a result, we can use a base QIOOperation to represent the async call, and just check its error code. The new tests are designed with the assumption that flush() would act as a barrier operation, making sure that all read/write operations before it will finish. Task-number: QTBUG-136763 Change-Id: I4119eb3218da1985a63fe808da7be754caf4e9d7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Work around QFileSystemEngine behavior on VxWorks hostFsKarim Pinter2025-09-171-18/+26
| | | | | | | | | | | | | | On VxWorks with hostFs (commonly used for debugging via Workbench), using QFile::exists() triggers a statfs() call, which fails. This change uses stat() check instead, which behaves more reliably in this context. Additionally, VxWorks stat() still incorrectly reports that the file has been deleted. This fix accounts for that false negative and avoids treating the file as missing. Task-number: QTBUG-139007 Pick-to: 6.8 6.9 6.10 Change-Id: Ie2cd277868e0d57bb8288271c8973da17162eef3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Add QRandomAccessAsyncFile and QIOOperationIvan Solovev2025-09-157-0/+1282
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For now, as a private API. The QRandomAccessAsyncFile class is supposed to handle async read and write operations. Note that some operations (e.g. open() and size()) are synchronous, because the tests showed that they normally would not block even if the file is not actually downloaded (e.g. stored on a MS OneDrive). The implementation for async calls is inspired by QNetworkAccessManager and QNetworkReply. The request for an async read or write returns a pointer to a QIOOperation object. That object will emit a finished() signal when the operation is complete, and an errorOccurred() signal, if there was any error. The user has to connect to these signals to handle the results. The typical usecase would be: QRandomAccessAsyncFile file; file.open(path, mode); auto op = file.read(offset, maxSize); connect(op, &QIOOperation::finished, &file, [op] { if (op->error() != QIOOperation::Error::None) // handle error // handle the data op->deleteLater(); }); Similarly to QNetworkReply, the user has to call deleteLater() in the callback that is connected to the signal. The API provides two types of methods: * owning methods that take ownership of the provided data-to-write or read into a buffer that is allocated internally. These are QRAAF::read() and QRAAF::write(). They exist for simplicity and user convenience. * non-owning methods that rely on the user to keep the provided buffers alive as long as the operation in not completed. These are QRAAF::readInto() and QRAAF::writeFrom(). They have overloads taking span-of-spans, which should allow to implement vectored IO. QIOOperation should become a public class at some point. This means that its APIs should be easy to use, and also extensible. It should not be limited to only Read and Write. The hierarchy of IO operations is represented by QIOOperation and its derived classes. The base class can be used when the user is not interested in the data of the operation, or if the operation should only report success of failure. The derived classes implement data() methods with various return types. The classes that represent Read and Write operations also additionally provide offset() and numBytesProcessed() methods. The patch also introduces QtPrivate::QIOOperationDataStorage that holds a std::variant of all possible values that the operation can contain. If needed, this variant can be extended to hold a QVariant in order to store an arbitrary value. This patch also provides the fallback QThreadpool-based implementation that simply executes the requests on the dedicated threadpool using QFuture. For simplicity, this implementation uses QFSFileEngine to provide all operations. The implementations for various backends should be added in follow-up patches. Task-number: QTBUG-136763 Change-Id: I8f34f9e78d91aa35756352de7fbe6544b58de23e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Add QFilePrivate::writeToDebugStreamTor Arne Vestbø2025-09-032-0/+13
| | | | | | | | | | | It's useful to see the file name of a file based QIODevice when debug logging it. Change-Id: Iaaa1639f4940024e9030b27da6219c959224bd3f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QProcess: replace Q_PRIVATE_SLOTs with new-style PMF-to-private connectsThiago Macieira2025-08-303-32/+20
| | | | | | | | | | | | | | Removes the string-based connections. We lose the vtable dispatch, which could be a problem if there are pending events that get delivered between ~QProcess() ends and ~QObject() clears the event queue. That is unlikely to happen because the intermediary class is QIODevice and it has no reason to deliver events on its destructor. Change-Id: I66f2a98a49babed69261fffdd99ba38939c3f59a Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QBuffer: replace Q_PRIVATE_SLOT with QMetaObject::invokeMethodThiago Macieira2025-08-302-17/+7
| | | | | | | | | | | | | | | There's a single call site, so this moves the effect closer to the cause and avoids a possible mistake in the string name. This delayed emission appears to exist so we "compress" the emission of those two signals and emit them only once, however many write() calls there may have been. We lose the vtable dispatch with this change, but that would only be a problem if a parent destructor (i.e., ~QIODevice()) posted events before ~QObject() cleared them. That is not the case now and unlikely to become so. Change-Id: I33cac248a651c88c7eb5fffd259f6b58a56d5d8a Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* moveToTrash/Unix: return QSystemError instead of using an output paramThiago Macieira2025-08-261-32/+33
| | | | | | | | | None of these functions require any more return information than success or failure, so we don't need q23::expected. Pick-to: 6.10 Change-Id: If5532378b299ce5f16f9fffd0dcde4614159d735 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* moveToTrash/XDG: allow $XDG_DATA_HOME/Trash to be a symlinkThiago Macieira2025-08-261-11/+13
| | | | | | | | | | | | | | | | | | | | | | | This is in the user's $HOME dir and thus entirely controlled by the user, so we don't need to apply the strict protections that the XDG spec requires of other dirs. The trash spec[1] being one long section without structures made the reading ambiguous whether the checks should also be applied to $HOME. This commit also allows the "info" and "files" subdirs to be symlinks, but I'm not testing that. [ChangeLog][QtCore][QFile] Fixed a bug that caused moveToTrash() to disallow trashing to trash bins using the XDG Trash Specification when the trash path was a symlink. [1] https://specifications.freedesktop.org/trash-spec/1.0/ Pick-to: 6.8 6.9 6.10 Fixes: QTBUG-138984 Change-Id: I4f05391082bc607389e0fffd06a9b72fdd098f22 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
* Add QFileSelectorPrivate::removeStatics(const QStringList &)Oliver Eftevaag2025-08-262-0/+9
| | | | | | | | | | | | | | | | | | There's currently no way to clear selectors that were added by external modules. For Qt Quick in particular, this means that QML modules that are loaded by the type loader can add static selectors to the global list, and if that module is later unloaded, those selectors can't be removed, and will exist for as long as a Qt application is running. It would make sense for selectors that were added in QQmlExtensionPlugin::registerTypes() reimplemented functions to be removed from the list when QQmlExtensionPlugin::unregisterTypes(), otherwise it would count as littering. Change-Id: I5dd66a175b3f7eecf793d67394cde136175e5d1f Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Log registered QLoggingCategoriesXavier BESSON2025-08-261-0/+21
| | | | | | | | | | | | Add logs for each registered QLoggingCategories under a special category called "_logging_categories" This can be used by a 3rd party software reading the logs to know what are all the available categories and help it filter them. Task-number: QTCREATORBUG-33169 Change-Id: I082658e9b36088f1cad1982a2f7115f924adf8e6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QFileSystemEngine/Unix: work around FreeBSD bug in copy_file_range(2)Thiago Macieira2025-08-221-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Amends commit 9b006eb91a612456f269161f79711e6fff3ccde0, which introduced the use of this function. When I tested this with FreeBSD 14.2, this code worked; now with 14.3 it doesn't, because on output the srcoffset and dstoffset variables are still zero, in spite of having copied content. That caused the copy_file_range() loop to copy the same files over and over again, never exiting. I've tracked this down to a change in 14.3[1] which showed that if both inoffp and outoffp were non-NULL, it wouldn't update. FreeBSD maintainers report this is already fixed[2] and will be made available soon. tst_qfile now passes again on FreeBSD. strace output on Linux: ioctl(5, BTRFS_IOC_CLONE or FICLONE, 4) = -1 EOPNOTSUPP (Operation not supported) copy_file_range(4, [0], 5, NULL, 9223372036854775807, 0) = 13587 copy_file_range(4, [13587], 5, NULL, 9223372036854775807, 0) = 0 truss output on FreeBSD: copy_file_range(0x4,0x32fb9588e360,0x5,0x0,0x7fffffffffffffff,0x0) = 624 (0x270) copy_file_range(0x4,0x32fb9588e360,0x5,0x0,0x7fffffffffffffff,0x0) = 0 (0x0) No changelog because the content is new in 6.10. [1] https://github.com/freebsd/freebsd-src/commit/1d2fd8c9cf0fb796d8b7b7590288d3125398d445 [2] https://github.com/freebsd/freebsd-src/commit/4046ad6bb0ee542a42d89a48a7d6a56564ed7f33 Pick-to: 6.10 Fixes: QTBUG-138570 Change-Id: I31ddcefb63bb738f0cc0fffd75d9f68030952ed5 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QMessageLogger: drop inline keyword from noDebug() out-of-body definitionMarc Mutz2025-08-211-1/+2
| | | | | | | | | | | | | | | Out-of-body definitions of inline functions should not have an inline keyword themselves, because it's superfluous and can hide problems (like the declaration not being marked as inline, which often trips up MinGW; without the inline keyword on the definition, such errors are caught on all platforms at link time). Amends 4fa44a70bc27939d653203a5d1cf303d044ca2f1. Pick-to: 6.10 Change-Id: I2039c8b3c430835406a7711ff0319d161d6c5cbb Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListing: add QDebug streaming operator for IteratorFlagsAhmad Samir2025-08-102-0/+54
| | | | | | | Like the one for QDir::Filters, makes it easier to debug the code. Change-Id: I9b045323effec40e9ebabd8f2f32aa2433b7c13c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QAbstractFileEngine: remove entryList() functionsAhmad Samir2025-08-102-43/+1
| | | | | | | | | | | | This is private API, and as pointed out in code review, entryList(QDir::Filters) became redundant since Qt 4.8: https://code.qt.io/cgit/qt/qt.git/commit/?id=859c0d5f2fe8234e9f1b8f638a3e3c592e7f3224 entryList(QDirListing::IteratorFlags) is relatively new and also unused, it was added for feature parity with the other overload. Change-Id: Ie39f194bf9df773d88798267f3df2974a66e83d1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListing: clarify that "name filters" use regular expressionsAhmad Samir2025-08-101-1/+8
| | | | | | | | | Also add a code snippet showing how filtering can be done by name using QString API, without regex. Pick-to: 6.10 6.9 6.8 Change-Id: Iee63da4590e4868f3dc3d8db0e99ba9bf64a4e0e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListing: add a QDirIterator to QDirListing porting guideAhmad Samir2025-08-102-3/+4
| | | | | | | Pick-to: 6.10 6.9 6.8 Task-number: QTBUG-138403 Change-Id: I3a7980c1a9b455f92722943b27034b02d2c203cc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDir: deprecate QDir::Filter::Modified flagAhmad Samir2025-08-102-5/+4
| | | | | | | | | I didn't find any usage of it in Qt code. [ChangeLog][QtCore][QDir] Deprecated QDir::Filter::Modified flag. Change-Id: I800fa6b177c2697c9621307d04090b566290012b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDir: add some API docs to checkNonDirListingFlags()Ahmad Samir2025-08-101-0/+6
| | | | | Change-Id: I6825fd32dd177d034d4f20a10674ffde96835c34 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListingPrivate: init() now takes no argsAhmad Samir2025-08-091-6/+4
| | | | | | | | | | | | It had a bool arg mimicking the original QDirIterator code. This was needed because QDI had a ctor that took a QDir (and QDI itself at one point in the distant past inherited QDir), and the resovleEngine arg was set to true/false depending on the QDirPrivate::fileEngine pointer. This isn't the case any more, and looking back, QDirListingPrivate::init() has always been called with a true arg. Change-Id: Ib488ca459234e22653c6efe4013adb1343a2d19c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListing: remove the private ctor that takes a QDir::FiltersAhmad Samir2025-08-093-157/+3
| | | | | | | | | Port the last user of this constructor in QAbstractFileEngine. Remove the legacy filters bits from QDirListing. Change-Id: I6d6ba61e113b6d964967e4155529dfb4d0ea82b6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Port away from private QDirListing ctor [3]: QFileInfoGathererAhmad Samir2025-08-091-1/+0
| | | | | | | | | | After adding IF::IncludeBrokenSymlinks, all the flags here can now be represented with QDirListing::IteratorFlags. Consquently there is no need to use QDirPrivate::checkNonDirListingFlags(). Change-Id: Ib2c5b48d4f47ec5ce825149ff990e5938aa7dce3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDirListing: port away from QDirListing private ctor [2]: QDirIteratorAhmad Samir2025-08-092-11/+31
| | | | | | | Using the same technique used in QDir. Change-Id: Ie60ec5775b78fbf131fe2fdeab9f4754b8cdfa91 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>