194 Commits

Author SHA1 Message Date
Łukasz Matysiak
fd1066ad41 Force requested permissions when calling mkdir on VxWorks
Calling mkdir with mode == 0 works just fine on Linux - it creates a
directory and the permissions are set to 0.
On VxWorks, calling mkdir with mode == 0 uses the default mode set in
the system.
This leads to a failing test (tst_QDir::mkdirWithPermissions(0000)) and
potential confusion when the same code does not behave in the same way
when called on Linux and VxWorks.

To keep the same interface between unix-like systems, explicitly set the
permissions to 0 when on VxWorks.

Pick-to: 6.7
Task-number: QTBUG-115777
Change-Id: I75e429c086500cb7c19f9bb14693bb4266e18046
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Michał Łoś <michal.los@siili.com>
(cherry picked from commit 90e79aea8e3f297de65a69d4e6c82a5d753b9c86)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-06-20 19:30:18 +00:00
Łukasz Matysiak
d594fbf12a 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>
2024-06-16 21:57:12 +00:00
Thiago Macieira
e32009fc0d QFileSystemEngine::canonicalName: don't use malloc()'ing realpath()
It is available in POSIX.1-2008 but is not worth it. The Linux man page
says it only works up to PATH_MAX anyway and the POSIX documentation
says it's UB if PATH_MAX isn't defined.

This cleans up the source code out of these messy #if and should be
faster, because we avoid a heap allocation (stack is always faster).

Instead, we only relegate the heap version to the case where PATH_MAX
isn't defined (i.e., GNU HURD), because in that case the realpath()
function can't be used with a stack allocation.

Pick-to: 6.7
Change-Id: Ie30a3caf09ef4176bb36fffd17cde1ed5c5dad59
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2024-05-24 21:34:27 +00:00
Łukasz Matysiak
f097cbd9bf Make QFileSystemEngine::canonicalName use the realpath function on VxWorks
Despite realpath being available on VxWorks (when the INCLUDE_IO_REALPATH
component is used in the VIP), canonicalName doesn't use it, because
the system reports _POSIX_VERSION as 200112.

Fix the problem by adding an additional condition so that VxWorks
correctly uses realpath.

Pick-to: 6.7
Task-number: QTBUG-115777
Change-Id: I734f525e870f93a7ec955d379dcc2137b591e171
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 10:15:42 +02:00
Ahmad Samir
fd295f4bf6 QAbstractFileEngine: remove member FileTime and use QFile::FileTime
This is probably a remnant from when QAbstractFileEngine was public API
since it's been changed to private API, just use QFile::FileTime.

Pick-to: 6.7
Change-Id: I60d3d4ff811f95434b81d5ca115f5d43cfff8b15
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-03-21 19:05:02 +02:00
Tor Arne Vestbø
2a2a301557 Apple: Fix a few deprecation warnings after bumping deployment targets
- kIOMasterPortDefault -> kIOMainPortDefault
 - Use UTType instead of Carbon Core functions/constants
 - NSWorkspace iconForFileType -> iconForContentType
 - Removed obsoleted kUTTypeInkText pasteboard type

There are still a few more, but these will be fixed in follow ups.

Change-Id: Ibbca226d578b4ba64bd9c8c5d0addc1870114a20
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2024-02-19 18:03:11 +01:00
Krzysztof Sommerfeld
21196d26d8 Make use of methods defined in utils unix layer
Some unix-like concepts are supported by VxWorks VSB layer - UTILS_UNIX.
One of such methods is getgrgid(). Include it in
`qfilesystemengine_unix.cpp`, so that we don't need to exclude VxWorks from code that uses it anymore.

Task-number: QTBUG-115777
Change-Id: I72b301647bfdb208cb6859bb0f9994e3537fc345
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-02-06 15:23:42 +00:00
Ahmad Samir
6d9185c0e6 QFileSystemEngine: use nativeFilePath()
Instead of filePath() then converting to QByteArray.

Change-Id: I6f656774979bedde5c657613303518750ab06855
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-02-01 23:42:56 +02:00
Marcin Zdunek
1d4ab5c135 Remove qfunctions_vxworks files and usage as it is no longer needed
Task-number: QTBUG-115777
Change-Id: I0d803ac7ce067737b79a39a267a2b0eb509ae0b8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-01-25 12:21:41 +01:00
Thiago Macieira
d5393a936d moveToTrash/Unix: use linkat() to check early for cross-device renames
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>
2023-10-26 11:36:46 -07:00
Thiago Macieira
c94bed69b7 moveToTrash/Unix: refactor to use openat()/mkdirat()/renameat()
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>
2023-10-17 19:08:25 -07:00
Thiago Macieira
25b1990784 moveToTrash/Unix: use the file's inode number as collision avoidance
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>
2023-10-17 19:08:25 -07:00
Thiago Macieira
77c661b275 moveToTrash/Unix: use lower-level API to write the info file
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>
2023-10-17 19:08:25 -07:00
Thiago Macieira
6359e8b8bd moveToTrash/Unix: avoid creating too many QStorageInfo
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>
2023-10-17 19:08:25 -07:00
Thiago Macieira
de24134aa7 moveToTrash/Unix: avoid TOCTOU in creating the unique file name
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>
2023-10-17 19:08:25 -07:00
Thiago Macieira
1c5575f194 moveToTrash/Unix: trust freeDesktopTrashLocation() to find the directory
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>
2023-10-17 19:08:24 -07:00
Thiago Macieira
61d99530c8 moveToTrash/Unix: avoid QFileInfo to get an absolute file name
We know what engine we're using, so don't go the long way around via
QFileInfo and QFSFileEngine to get back to QFileSystemEngine in order to
calculate an absolute and clean path.

Since we're doing that, we may as well use QFileSystemEntry's ability to
give us the file name portion of this absolute path without having to go
via QFileInfo and QDir again. We just need to make sure that a dir name
isn't ending in a slash: absoluteName() would remove that for us, but
only if the entry isn't already absolute and clean.

Change-Id: I9d43e5b91eb142d6945cfffd17871389d359e750
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-10-06 18:43:30 -07:00
Thiago Macieira
fa97531952 moveToTrash/Unix: reorganize the #ifdef
Change-Id: I9d43e5b91eb142d6945cfffd178708f58b71e7ef
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-10-06 18:43:29 -07:00
Thiago Macieira
36a169e31e moveToTrash/Unix: use lstat() to confirm $root/.Trash is suitable
We can't use QFileSystemEngine::fillMetaData() because there's no bit in
QFileSystemMetaData to indicate the sticky flag, so we must make a at
least one stat() or lstat() call ourselves. Given that we need to know
if $root/.Trash is a symlink, that system call must be lstat(). And it
turns out that system call provides everything we need to confirm its
suitability.

This avoids QDir overhead just to manipulate strings.

Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786c5e54199ecb2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-09-23 16:16:09 -07:00
Thiago Macieira
3d027f8d95 moveToTrash/Unix: remove unnecessary targetPath variable
It was used twice, in both cases to create a QFileSystemEntry, so the
two results were equal. Therefore, just use the first result to create
the second.

Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786d45d20485f40
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-09-23 08:18:31 -07:00
Thiago Macieira
6434b6ea48 moveToTrash/Unix: rename 'infoPath' variable to 'pathForInfo'
We have other variables whose name start with 'info' in this function,
so infoPath is misleading: it's not the path to infoFile and it isn't
related to the infoFileName. Instead, it's the path to the file being
trashed which will be saved in the info file.

Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786d358a0e02dfd
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-09-23 08:18:30 -07:00
Thiago Macieira
6e4d9ff74d moveToTrash/Unix: use Qt::ISODate to format the current date
Instead of forcing QDateTime to parse our pattern.

Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786d094a123826a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-09-23 08:18:23 -07:00
Thiago Macieira
a71f556830 moveToTrash/Unix: avoid mkdir/chmod race condition for the trash dir
QDir::mkdir() followed by QFile::setPermissions() is a race condition
because an attacker could enter the directory before we set the
permissions. QDir::mkdir() got an overload with the permissions in 6.3,
but I decided to go a level lower and use QFileSystemEngine directly
here.

Pick-to: 6.5 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786c338e21c129e
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-09-23 08:18:22 -07:00
Jacek Poplawski
43480998ef Fix compilation of qfilesystemengine on VxWorks
Change-Id: I533f262bf6624008d216d96aa29ae2dfc4ba9195
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-27 20:13:55 +02:00
Edward Welbourne
db5279825c Corelib: s/Q_OS_MAC/Q_OS_DARWIN/wg except for doc and definition
I got tired of being told off by the inanity 'bot for faithfully
reflecting existing #if-ery in new #if-ery. Retain only the
documentation and definition of the deprecated define.

Change-Id: I47f47b76bd239a360f27ae5afe593dfad8746538
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2023-03-20 19:18:52 +01:00
Ahmad Samir
8a1eb24de8 Misc: Fix qsizetype-related narrowing coversions
Task-number: QTBUG-102461
Change-Id: I96757abc50fc45756bc1271a970f819a48021663
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-03-11 12:39:47 +02:00
Ahmad Samir
dda60cf0d1 sysconf() system function returns long
Change-Id: Ia7218c1cc0e8ec55822aee55d7643d6df48efa8b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-03-11 12:39:41 +02:00
Ahmad Samir
683ddddc6a q_core_unix: move timspec<->chrono helpers from qtools_p.h
Where it has a home with its other timespec/chrono siblings.

Luckily I only needed to change one place in the code, and that source
file already has #include's q_core_unix_p.h.

Change-Id: I783383f958ceccfd6f9210f0b76d35b0f82b7cb5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-25 23:11:54 +02:00
Ahmad Samir
dd82f39910 QtMiscUtils: add std::chrono::duration <-> timespec helpers
Change-Id: I91f36a3d651fd57443072fde4c3e8f811682328e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-20 21:28:38 +02:00
Jonas Kvinge
314a4d121f QFileSystemEngine: URL encode path in trash info, use relative path
According to the specifications, the path in .trashinfo should be URL
encoded.

The path can be relative when possible, otherwise changing the
mountpoint will break restoring files from trash.
But don't do that for root (/) and home.

For more info, see.:
https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html

Pick-to: 6.5 5.15
Change-Id: Id8271a893a007f4cb5c10611f2b1bc71c1ff4860
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-02 17:39:37 +01:00
Wang Fei
936cae6b53 Add QFileInfo::readSymLink() to read the raw link path
The existing symLinkTarget() always resolves the symlink target to an
absolute path; readSymLink() provides access to the relative path when
that is how the symlink references its target.

[ChangeLog][QtCore][QFileInfo] Added readSymLink() to read the symlink's
raw target, without resolving to an absolute path.

Fixes: QTBUG-96761
Change-Id: I360e55f1a3bdb00e2966229ea8de78cf29a29417
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-23 06:26:44 +01:00
Ahmad Samir
7566c7381d QFileSystemEngine/Unix: use chrono for time related arithmetic
Change-Id: I1647c6ab44ec5c3569411cca88738746e44cc4b2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-15 12:44:26 +02:00
Ahmad Samir
cb9d76169a QFileSystemEngine/Unix: remove futimes related code
- futimes isn't a standard system call[1]:
«
This system call is nonstandard.  It was implemented from a specification
that was proposed for POSIX.1, but that specification was replaced by the
one for utimensat(2).

A similar system call exists on Solaris.
»
[1] https://man7.org/linux/man-pages/man2/futimesat.2.html
[2] https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html

- futimens is a standard system call[2], it's available on:
 - Linux: https://man7.org/linux/man-pages/man2/futimesat.2.html
 - FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=futimens&sektion=2&n=1
 - OpenBSD: https://man.openbsd.org/futimens.2
 - QNX: https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/futimens.html

So, remove futimes related code.

Change-Id: I58ac466f08161a88219e3a32eab98d168f065140
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-11-09 14:22:29 +02:00
Marc Mutz
df9d882d41 Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:

  auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
  makeRule(cxxMemberCallExpr(on(QtContainerClass),
                             callee(cxxMethodDecl(hasAnyName({"count", "length"),
                                                  parameterCountIs(0))))),
           changeTo(cat(access(o, cat("size"), "()"))),
           cat("use 'size()' instead of 'count()/length()'"))

a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.

<classes> are:

    // sequential:
    "QByteArray",
    "QList",
    "QQueue",
    "QStack",
    "QString",
    "QVarLengthArray",
    "QVector",
    // associative:
    "QHash",
    "QMultiHash",
    "QMap",
    "QMultiMap",
    "QSet",
    // Qt has no QMultiSet

Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-10-04 07:40:08 +02:00
Lucie Gérard
05fc3aef53 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-05-16 16:37:38 +02:00
Sona Kurazyan
908e85cc85 Replace uses of _qs with _s in sources and examples
Task-number: QTBUG-101408
Change-Id: I48360ba3b23965cd3d90ac243c100a0656a4cde8
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-04-19 19:12:20 +02:00
Sona Kurazyan
b625195893 QtCore: Replace remaining uses of QLatin1String with QLatin1StringView
Task-number: QTBUG-98434
Change-Id: Ib7c5fc0aaca6ef33b93c7486e99502c555bf20bc
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-03-26 01:44:05 +01:00
Sona Kurazyan
753a08ae0e QtCore: replace QLatin1String/QLatin1Char with _L1/u'' where applicable
As a drive-by, did also minor refactorings/improvements.

Task-number: QTBUG-98434
Change-Id: I81964176ae2f07ea63674c96f47f9c6aa046854f
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
2022-03-25 19:16:29 +01:00
Marc Mutz
bbae5c891b QFileSystemEngine: fix potential formatting error
It's not immediately clear that trashedName doesn't contain %1 or %2,
in which case the subsequent .arg() would replace that instead of the
intended %2.

Fix by using QString::asprintf(), which doesn't perform multiple
interpolation passes.

Pick-to: 6.3 6.2 5.15
Change-Id: Ib6c24bfea01db4cdc80f7547c8269cce3f815158
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
2022-03-15 20:05:31 +00:00
Tor Arne Vestbø
34b5e38f20 Distinguish macOS aliases from normal symbolic links
The deprecated Carbon function FSIsAliasFile() returned isAlias only for
actual aliases, whereas the replacement CFURLCopyResourcePropertyForKey
with kCFURLIsAliasFileKey returns true for both aliases and symbolic
links.

Since we didn't explicitly check for AliasType in any of our internal
code, or or any of the public API, the distinction did not cause any
issues, but if we want to expose QFileInfo::isAlias() we need to fix
this.

Pick-to: 6.2 6.3 5.15
Change-Id: I29f795d55fe40898de319aa1cb0a4a1b5646bbd6
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-03-06 18:46:48 +01:00
Fabian Kosmale
06e45cbd6a QFileSystemEngine::canonicalName (Unix): clean up control-flow
When passing a nullptr to realpath, it will allocate memory. That memory
has to be freed (with free) later to avoid a leak, which we so far
didn't.
This patch ensures that we always clean up the memory by using a
unique_ptr. As a drive-by, clean up the control-flow:
- Always pass either the stack buffer or nullptr to realpath.
- Rely on realpath returning nullptr in the error case.
Lastly, fix a few coding-style issues.

Change-Id: Ia906df77324020c267b087ec52a9a6c47aaa2a59
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-02-15 12:05:33 +01:00
Pino Toscano
7c54988b1b Avoid a stack buffer when not needed
Allocate a PATH_MAX-sized buffer on stack only in case we are not using
realpath(X, null), i.e. on platforms with older POSIX versions, macOS,
or Android.

This fixes the build on platforms that do not have PATH_MAX (e.g.
GNU/Hurd), and it provides a minor optimization on realpath(X, null)
platforms.

Change-Id: Icd92a1b15ec18c5eef8113408e9610dfac774101
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-02-11 15:36:02 +01:00
Ievgenii Meshcheriakov
174af05400 QDir: Add support for setting directory permissions to mkdir()
This patch adds an overload of the QDir::mkdir() method that
accepts permissions. This allows setting of the directory
permissions at the time of its creation.

[ChangeLog][QtCore][QDir] Added QDir::mdkir() overload that
accepts permissions argument.

Task-number: QTBUG-79750
Change-Id: Ic9db723b94ff0d2da6e0b819ac2e5d1f9a4e2049
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2021-11-26 03:39:33 +01:00
Ievgenii Meshcheriakov
1cc9ac71ac Move toMode_t() from qfilesystemengine_unix.cpp to qfiledevice_p.h
The function is needed in multiple files to implement QDir::mkdir()
and QFile::open() methods that accept a permission argument on Unix.

Task-number: QTBUG-79750
Change-Id: Ib0853f7d12bcb5d6f1116b43ec1aa07b6554bb93
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2021-11-10 18:22:07 +01:00
Karsten Heimrich
bb8d84c358 Make QDir::mkpath() return true when given an existing root path
On macOs with APFS mkdir sets errno to EISDIR, so take the error code
into account.

Pick-to: 6.2
Fixes: QTBUG-97110
Change-Id: I8e7d10c95430a2802bdbfbf94dd65219bd9071a7
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2021-10-20 15:04:51 +00:00
David Skoland
3fc58a5ed8 Remove union in QFileSystemEngine
The need for this union has disappeared at some point during refactoring
It does confuse MemorySanitizer, though, so it's good to remove it.

Change-Id: I5f5050adba302bf96db96d5f303d2a25630543ce
Fixes: QTBUG-97109
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2021-10-11 15:46:46 +02:00
Giuseppe D'Angelo
4cc2f48628 QF*Engine: port a couple of QFlags->int implicit conversions to toInt()
Change-Id: Iafc3527941a0b56a680322e3bc05b4046e560e89
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2021-06-23 12:49:19 +02:00
Alexander Volkov
9667ac1c2d Call statx() with AT_NO_AUTOMOUNT
Otherwise it can be very slow in some cases (e.g. 0.5 sec).
Besides, AT_NO_AUTOMOUNT is used by {l,f}stat() internally.

Pick-to: 6.1 6.0 5.15
Change-Id: Iae9c8b46dcdc96d21ac6b114a51c382b4949d3dd
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2021-04-08 17:57:36 +00:00
Allan Sandfeld Jensen
c82f73666d Replace Q_DECL_UNUSED with [[maybe_unused]]
Use C++17 attribute directly

Change-Id: Id853e7a5117065e4adb549f81303c1820fe198ce
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2020-10-03 11:58:08 +02:00
Thiago Macieira
d8d7dbb65a Compile on QNX after QFlags constructor deprecation
The QFlags constructor taking a plain zero literal was deprecated in
commit af2daafde72db02454d24b7d691aa6861525ab99.

Pick-to: 5.15
Fixes: QTBUG-86585
Change-Id: I2fc68c725ba649218bd9fffd1633d6251649d2bd
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2020-09-13 12:04:47 -07:00