summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qcore_unix_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qcore_unix_p.h')
-rw-r--r--src/corelib/kernel/qcore_unix_p.h137
1 files changed, 87 insertions, 50 deletions
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 9ccc9ca10b..fd834cb2d9 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -18,8 +18,8 @@
#include "qplatformdefs.h"
#include <QtCore/private/qglobal_p.h>
-#include "qatomic.h"
#include "qbytearray.h"
+#include "qdeadlinetimer.h"
#ifndef Q_OS_UNIX
# error "qcore_unix_p.h included on a non-Unix system"
@@ -39,14 +39,11 @@
# include <selectLib.h>
#endif
+#include <chrono>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
-#if !defined(QT_POSIX_IPC) && !defined(QT_NO_SHAREDMEMORY) && !defined(Q_OS_ANDROID)
-# include <sys/ipc.h>
-#endif
-
#if defined(Q_OS_VXWORKS)
# include <ioLib.h>
#endif
@@ -59,7 +56,7 @@
struct sockaddr;
-#define EINTR_LOOP(var, cmd) \
+#define QT_EINTR_LOOP(var, cmd) \
do { \
var = cmd; \
} while (var == -1 && errno == EINTR)
@@ -68,16 +65,41 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(pollfd, Q_PRIMITIVE_TYPE);
+static constexpr auto OneSecAsNsecs = std::chrono::nanoseconds(std::chrono::seconds{ 1 }).count();
+
+inline timespec durationToTimespec(std::chrono::nanoseconds timeout) noexcept
+{
+ using namespace std::chrono;
+ const seconds secs = duration_cast<seconds>(timeout);
+ const nanoseconds frac = timeout - secs;
+ struct timespec ts;
+ ts.tv_sec = secs.count();
+ ts.tv_nsec = frac.count();
+ return ts;
+}
+
+template <typename Duration>
+inline Duration timespecToChrono(timespec ts) noexcept
+{
+ using namespace std::chrono;
+ return duration_cast<Duration>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec});
+}
+
+inline std::chrono::milliseconds timespecToChronoMs(timespec ts) noexcept
+{
+ return timespecToChrono<std::chrono::milliseconds>(ts);
+}
+
// Internal operator functions for timespecs
constexpr inline timespec &normalizedTimespec(timespec &t)
{
- while (t.tv_nsec >= 1000000000) {
+ while (t.tv_nsec >= OneSecAsNsecs) {
++t.tv_sec;
- t.tv_nsec -= 1000000000;
+ t.tv_nsec -= OneSecAsNsecs;
}
while (t.tv_nsec < 0) {
--t.tv_sec;
- t.tv_nsec += 1000000000;
+ t.tv_nsec += OneSecAsNsecs;
}
return t;
}
@@ -104,7 +126,7 @@ constexpr inline timespec operator-(const timespec &t1, const timespec &t2)
{
timespec tmp = {};
tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1);
- tmp.tv_nsec = t1.tv_nsec - (t2.tv_nsec + 1000000000);
+ tmp.tv_nsec = t1.tv_nsec - (t2.tv_nsec + OneSecAsNsecs);
return normalizedTimespec(tmp);
}
constexpr inline timespec operator*(const timespec &t1, int mul)
@@ -114,7 +136,7 @@ constexpr inline timespec operator*(const timespec &t1, int mul)
tmp.tv_nsec = t1.tv_nsec * mul;
return normalizedTimespec(tmp);
}
-inline timeval timespecToTimeval(const timespec &ts)
+inline timeval timespecToTimeval(timespec ts)
{
timeval tv;
tv.tv_sec = ts.tv_sec;
@@ -122,23 +144,44 @@ inline timeval timespecToTimeval(const timespec &ts)
return tv;
}
+inline timespec &operator+=(timespec &t1, std::chrono::milliseconds msecs)
+{
+ t1 += durationToTimespec(msecs);
+ return t1;
+}
-inline void qt_ignore_sigpipe()
+inline timespec &operator+=(timespec &t1, int ms)
{
- // Set to ignore SIGPIPE once only.
- Q_CONSTINIT static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (!atom.loadRelaxed()) {
- // More than one thread could turn off SIGPIPE at the same time
- // But that's acceptable because they all would be doing the same
- // action
- struct sigaction noaction;
- memset(&noaction, 0, sizeof(noaction));
- noaction.sa_handler = SIG_IGN;
- ::sigaction(SIGPIPE, &noaction, nullptr);
- atom.storeRelaxed(1);
+ t1 += std::chrono::milliseconds{ms};
+ return t1;
+}
+
+inline timespec operator+(const timespec &t1, std::chrono::milliseconds msecs)
+{
+ timespec tmp = t1;
+ tmp += msecs;
+ return tmp;
+}
+
+inline timespec operator+(const timespec &t1, int ms)
+{
+ return t1 + std::chrono::milliseconds{ms};
+}
+
+inline timespec qAbsTimespec(timespec ts)
+{
+ if (ts.tv_sec < 0) {
+ ts.tv_sec = -ts.tv_sec - 1;
+ ts.tv_nsec -= OneSecAsNsecs;
+ }
+ if (ts.tv_sec == 0 && ts.tv_nsec < 0) {
+ ts.tv_nsec = -ts.tv_nsec;
}
+ return normalizedTimespec(ts);
}
+Q_CORE_EXPORT void qt_ignore_sigpipe() noexcept;
+
#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
# if !__GLIBC_PREREQ(2, 22)
Q_CORE_EXPORT int qt_open64(const char *pathname, int flags, mode_t);
@@ -147,6 +190,16 @@ Q_CORE_EXPORT int qt_open64(const char *pathname, int flags, mode_t);
# endif
#endif
+#ifdef AT_FDCWD
+static inline int qt_safe_openat(int dfd, const char *pathname, int flags, mode_t mode = 0777)
+{
+ // everyone already has O_CLOEXEC
+ int fd;
+ QT_EINTR_LOOP(fd, openat(dfd, pathname, flags | O_CLOEXEC, mode));
+ return fd;
+}
+#endif
+
// don't call QT_OPEN or ::open
// call qt_safe_open
static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777)
@@ -155,7 +208,7 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
flags |= O_CLOEXEC;
#endif
int fd;
- EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode));
+ QT_EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode));
#ifndef O_CLOEXEC
if (fd != -1)
@@ -227,10 +280,10 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
int ret;
#ifdef QT_THREADSAFE_CLOEXEC
// use dup3
- EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
+ QT_EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
return ret;
#else
- EINTR_LOOP(ret, ::dup2(oldfd, newfd));
+ QT_EINTR_LOOP(ret, ::dup2(oldfd, newfd));
if (ret == -1)
return -1;
@@ -243,7 +296,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
{
qint64 ret = 0;
- EINTR_LOOP(ret, QT_READ(fd, data, maxlen));
+ QT_EINTR_LOOP(ret, QT_READ(fd, data, maxlen));
return ret;
}
#undef QT_READ
@@ -252,7 +305,7 @@ static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static inline qint64 qt_safe_write(int fd, const void *data, qint64 len)
{
qint64 ret = 0;
- EINTR_LOOP(ret, QT_WRITE(fd, data, len));
+ QT_EINTR_LOOP(ret, QT_WRITE(fd, data, len));
return ret;
}
#undef QT_WRITE
@@ -267,7 +320,7 @@ static inline qint64 qt_safe_write_nosignal(int fd, const void *data, qint64 len
static inline int qt_safe_close(int fd)
{
int ret;
- EINTR_LOOP(ret, QT_CLOSE(fd));
+ QT_EINTR_LOOP(ret, QT_CLOSE(fd));
return ret;
}
#undef QT_CLOSE
@@ -279,28 +332,28 @@ static inline int qt_safe_execve(const char *filename, char *const argv[],
char *const envp[])
{
int ret;
- EINTR_LOOP(ret, ::execve(filename, argv, envp));
+ QT_EINTR_LOOP(ret, ::execve(filename, argv, envp));
return ret;
}
static inline int qt_safe_execv(const char *path, char *const argv[])
{
int ret;
- EINTR_LOOP(ret, ::execv(path, argv));
+ QT_EINTR_LOOP(ret, ::execv(path, argv));
return ret;
}
static inline int qt_safe_execvp(const char *file, char *const argv[])
{
int ret;
- EINTR_LOOP(ret, ::execvp(file, argv));
+ QT_EINTR_LOOP(ret, ::execvp(file, argv));
return ret;
}
static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
{
int ret;
- EINTR_LOOP(ret, ::waitpid(pid, status, options));
+ QT_EINTR_LOOP(ret, ::waitpid(pid, status, options));
return ret;
}
#endif // QT_CONFIG(process)
@@ -309,9 +362,6 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
# define _POSIX_MONOTONIC_CLOCK -1
#endif
-// in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp
-timespec qt_gettime() noexcept;
-void qt_nanosleep(timespec amount);
QByteArray qt_readlink(const char *path);
/* non-static */
@@ -329,20 +379,7 @@ inline bool qt_haveLinuxProcfs()
#endif
}
-Q_CORE_EXPORT int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts);
-
-static inline int qt_poll_msecs(struct pollfd *fds, nfds_t nfds, int timeout)
-{
- timespec ts, *pts = nullptr;
-
- if (timeout >= 0) {
- ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000 * 1000;
- pts = &ts;
- }
-
- return qt_safe_poll(fds, nfds, pts);
-}
+Q_CORE_EXPORT int qt_safe_poll(struct pollfd *fds, nfds_t nfds, QDeadlineTimer deadline);
static inline struct pollfd qt_make_pollfd(int fd, short events)
{