Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qcore_unix.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// Copyright (C) 2016 Intel Corporation.
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:significant reason:default
5
6
#
include
<
QtCore
/
private
/
qglobal_p
.
h
>
7
#
include
<
QtCore
/
qbasicatomic
.
h
>
8
#
include
"qcore_unix_p.h"
9
10
#
include
<
stdlib
.
h
>
11
12
#
ifdef
__GLIBC__
13
#
include
<
sys
/
syscall
.
h
>
14
#
include
<
pthread
.
h
>
15
#
include
<
unistd
.
h
>
16
#
endif
17
18
#
ifdef
Q_OS_DARWIN
19
#
include
<
mach
/
mach_time
.
h
>
20
#
endif
21
22
QT_BEGIN_NAMESPACE
23
24
void
qt_ignore_sigpipe
()
noexcept
// noexcept: sigaction(2) is not a Posix Cancellation Point
25
{
26
// Set to ignore SIGPIPE once only.
27
Q_CONSTINIT
static
QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
28
if
(!atom.loadRelaxed()) {
29
// More than one thread could turn off SIGPIPE at the same time
30
// But that's acceptable because they all would be doing the same
31
// action
32
struct
sigaction noaction = {};
33
noaction.sa_handler = SIG_IGN;
34
::sigaction(SIGPIPE, &noaction,
nullptr
);
35
atom.storeRelaxed(1);
36
}
37
}
38
39
QByteArray
qt_readlink
(
const
char
*path)
40
{
41
#
ifndef
PATH_MAX
42
// suitably large value that won't consume too much memory
43
#
define
PATH_MAX
1024
*
1024
44
#
endif
45
46
QByteArray
buf(256, Qt::Uninitialized);
47
48
ssize_t len = ::readlink(path, buf.data(), buf.size());
49
while
(len == buf.size()) {
50
// readlink(2) will fill our buffer and not necessarily terminate with NUL;
51
if
(buf.size() >=
PATH_MAX
) {
52
errno = ENAMETOOLONG;
53
return
QByteArray
();
54
}
55
56
// double the size and try again
57
buf.resize(buf.size() * 2);
58
len = ::readlink(path, buf.data(), buf.size());
59
}
60
61
if
(len == -1)
62
return
QByteArray
();
63
64
buf.resize(len);
65
return
buf;
66
}
67
68
#
if
defined
(
Q_PROCESSOR_X86_32
)
&&
defined
(
__GLIBC__
)
69
#
if
!
__GLIBC_PREREQ
(
2
,
22
)
70
// glibc prior to release 2.22 had a bug that suppresses the third argument to
71
// open() / open64() / openat(), causing file creation with O_TMPFILE to have
72
// the wrong permissions. So we bypass the glibc implementation and go straight
73
// for the syscall. See
74
// https://sourceware.org/git/?p=glibc.git;a=commit;h=65f6f938cd562a614a68e15d0581a34b177ec29d
75
int
qt_open64(
const
char
*pathname,
int
flags, mode_t mode)
76
{
77
return
syscall(SYS_open, pathname, flags | O_LARGEFILE, mode);
78
}
79
#
endif
80
#
endif
81
82
#
ifndef
QT_BOOTSTRAPPED
83
84
#
if
QT_CONFIG
(
poll_pollts
)
85
#
define
ppoll
pollts
86
#
endif
87
88
[[maybe_unused]]
89
static
inline
int
timespecToMillisecs
(
const
struct
timespec *ts)
90
{
91
using
namespace
std
::chrono;
92
if
(!ts)
93
return
-1;
94
auto
ms = ceil<milliseconds>(timespecToChrono<nanoseconds>(*ts));
95
return
int
(ms.count());
96
}
97
98
// defined in qpoll.cpp
99
int
qt_poll
(
struct
pollfd *fds, nfds_t nfds,
const
struct
timespec *timeout_ts);
100
101
static
inline
int
qt_ppoll
(
struct
pollfd *fds, nfds_t nfds,
const
struct
timespec *timeout_ts)
102
{
103
#
if
QT_CONFIG
(
poll_ppoll
)
||
QT_CONFIG
(
poll_pollts
)
104
return
::ppoll(fds, nfds, timeout_ts,
nullptr
);
105
#
elif
QT_CONFIG
(
poll_poll
)
106
return
::poll(fds, nfds, timespecToMillisecs(timeout_ts));
107
#
elif
QT_CONFIG
(
poll_select
)
108
return
qt_poll(fds, nfds, timeout_ts);
109
#
else
110
// configure.json reports an error when everything is not available
111
#
endif
112
}
113
114
115
/*!
116
\internal
117
118
Behaves as close to POSIX poll(2) as practical but may be implemented
119
using select(2) where necessary. In that case, returns -1 and sets errno
120
to EINVAL if passed any descriptor greater than or equal to FD_SETSIZE.
121
*/
122
int
qt_safe_poll
(
struct
pollfd *fds, nfds_t nfds, QDeadlineTimer deadline)
123
{
124
if
(deadline.isForever()) {
125
// no timeout -> block forever
126
int
ret;
127
QT_EINTR_LOOP
(ret,
qt_ppoll
(
fds
,
nfds
,
nullptr
)
);
128
return
ret;
129
}
130
131
using
namespace
std
::chrono;
132
nanoseconds remaining = deadline.remainingTimeAsDuration();
133
// loop and recalculate the timeout as needed
134
do
{
135
timespec ts = durationToTimespec(remaining);
136
const
int
ret =
qt_ppoll
(
fds
,
nfds
,
&ts
)
;
137
if
(ret != -1 || errno != EINTR)
138
return
ret;
139
remaining = deadline.remainingTimeAsDuration();
140
}
while
(remaining > 0ns);
141
142
return
0;
143
}
144
145
#
endif
// QT_BOOTSTRAPPED
146
147
QT_END_NAMESPACE
QByteArray::FromBase64Result
\inmodule QtCore
Definition
qbytearray.h:824
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qt_safe_poll
int qt_safe_poll(struct pollfd *fds, nfds_t nfds, QDeadlineTimer deadline)
Definition
qcore_unix.cpp:122
qt_poll
int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
Definition
qpoll.cpp:137
timespecToMillisecs
static int timespecToMillisecs(const struct timespec *ts)
Definition
qcore_unix.cpp:89
qt_ignore_sigpipe
QT_BEGIN_NAMESPACE void qt_ignore_sigpipe() noexcept
Definition
qcore_unix.cpp:24
qt_ppoll
static int qt_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
Definition
qcore_unix.cpp:101
qt_readlink
QByteArray qt_readlink(const char *path)
Definition
qcore_unix.cpp:39
QT_EINTR_LOOP
#define QT_EINTR_LOOP(var, cmd)
Definition
qcore_unix_p.h:60
PATH_MAX
#define PATH_MAX
Definition
qfilesystemengine_win.cpp:51
qtbase
src
corelib
kernel
qcore_unix.cpp
Generated on
for Qt by
1.18.0