Make createDirectoryWithParents return true for existing dirs on read only fs

When the filesystem is mounted in a read only mode, Linux returns true
on an attempt to create a dir that already exists on that fs.
However not every platform behaves that way.

VxWorks is not a fully unix-like system.
It is possible to enable a component that provides a virtual root file
system (VRFS) so that devices and paths can be managed using "/" as a root.
The root itself is not an actual path that can be used like on other systems.
It is not possible to store files directly in "/".

On Linux, mkdir on "/" returns EEXIST.
On VxWorks, it returns EROFS (read only file system).

That leads to a failing test (tst_QDir::makedirReturnCode).
It also leads to a broken contract, since the doc for QDir::mkpath states that:
`If the path already exists when this function is called, it will return
true.`
The doc for createDirectoryWithParents has no such comment and it is
used by other functions that also do not promise such things, but the
implementation behaves that way anyway: when errno == EEXIST -> return
true if the target path is an existing directory.

Since the existing unix implementation already returns true for existing dirs
(without checking if it was called in the context of `mkpath` or any other
function), fix the problem by checking if errno == EROFS after a call
to mkdir and then checking if the target path already exists and is a directory

Pick-to: 6.7
Task-number: QTBUG-115777
Change-Id: I849bca56618bf675933cccc5a9d5313e0014628b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Karim Pinter <karim.pinter@qt.io>
Reviewed-by: Jarno Lämsä <jarno.lamsa@qt.io>
(cherry picked from commit 8915ae3a75c4a356d94962dd9b31e1458f2a506f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Łukasz Matysiak 2024-06-04 16:03:44 +02:00 committed by Qt Cherry-pick Bot
parent 788e9d7faa
commit d594fbf12a

View File

@ -1082,7 +1082,7 @@ static bool createDirectoryWithParents(const QByteArray &nativeName, mode_t mode
return true;
if (errno == EISDIR)
return true;
if (errno == EEXIST)
if (errno == EEXIST || errno == EROFS)
return isDir(nativeName);
if (errno != ENOENT)
return false;