summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarim Pinter <[email protected]>2025-05-02 16:13:38 +0300
committerKarim Pinter <[email protected]>2025-05-12 12:35:00 +0300
commit53756dcfbcb717327e26ee65cea995c2794e01fe (patch)
treebb6882573d066299b578a3ed2e3fe58ce41ea4ac
parent5ff542493dba52934d92f86463395e33b874906e (diff)
Add POSIX Pipe feature to VxWorks
VxWorks has POSIX pipe2 functions, but doesn't pass threadsafe-cloexec because it doesn't have threadsafe-cloexec dup3. By default on VxWorks POSIX pipes are used, but now it's possible to switch to PipeDrv pipes using "configure -feature-vxpipedrv ...". dup3 and accept4 test are now separated from threadsafe-cloexec test. Task-number: QTBUG-132889 Pick-to: 6.8 6.9 Change-Id: I9e4514e2795917e8f3685a1760ea82a0022e9ca2 Reviewed-by: Alexey Edelev <[email protected]> Reviewed-by: Thiago Macieira <[email protected]>
-rw-r--r--src/corelib/configure.cmake53
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h1
-rw-r--r--src/corelib/kernel/qcore_unix_p.h5
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp42
-rw-r--r--src/network/socket/qnet_unix_p.h2
5 files changed, 87 insertions, 16 deletions
diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake
index e2024bf03a9..8902194ed5d 100644
--- a/src/corelib/configure.cmake
+++ b/src/corelib/configure.cmake
@@ -132,6 +132,46 @@ int pipes[2];
}
")
+# dup3
+qt_config_compile_test(dup3
+ LABEL "dup3"
+ CODE
+"#define _GNU_SOURCE 1
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(void)
+{
+ /* BEGIN TEST: */
+(void) dup3(0, 3, O_CLOEXEC);
+ /* END TEST: */
+ return 0;
+}
+")
+
+# acccept4
+qt_config_compile_test(accept4
+ LABEL "accept4"
+ CODE
+"#define _GNU_SOURCE 1
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(void)
+{
+ /* BEGIN TEST: */
+#if defined(__NetBSD__)
+(void) paccept(0, 0, 0, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK);
+#else
+(void) accept4(0, 0, 0, SOCK_CLOEXEC | SOCK_NONBLOCK);
+#endif
+ /* END TEST: */
+ return 0;
+}
+")
+
# copy_file_range
qt_config_compile_test(copy_file_range
LABEL "copy_file_range()"
@@ -866,6 +906,19 @@ qt_feature("threadsafe-cloexec"
)
qt_feature_definition("threadsafe-cloexec" "QT_THREADSAFE_CLOEXEC" VALUE "1")
qt_feature_config("threadsafe-cloexec" QMAKE_PUBLIC_QT_CONFIG)
+qt_feature("dup3" PRIVATE
+ LABEL "dup3 support"
+ CONDITION TEST_dup3
+)
+qt_feature("accept4" PRIVATE
+ LABEL "accept4 support"
+ CONDITION TEST_accept4
+)
+qt_feature("vxpipedrv" PRIVATE
+ LABEL "Use pipedrv pipes on VxWorks"
+ AUTODETECT OFF
+ CONDITION VXWORKS
+)
qt_feature("regularexpression" PUBLIC
SECTION "Kernel"
LABEL "QRegularExpression"
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 97afd0cba01..09de82985e4 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -52,6 +52,7 @@
#define QT_NO_DATASTREAM
#define QT_FEATURE_datestring 1
#define QT_FEATURE_datetimeparser -1
+#define QT_FEATURE_dup3 -1
#define QT_FEATURE_easingcurve -1
#define QT_FEATURE_etw -1
#define QT_FEATURE_futimens -1
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 3fdd965f98b..e94ffab8e7c 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -270,7 +270,6 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
#undef QT_OPEN
#define QT_OPEN qt_safe_open
-#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
// don't call ::pipe
// call qt_safe_pipe
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
@@ -299,8 +298,6 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
#endif
}
-#endif // Q_OS_VXWORKS
-
// don't call dup or fcntl(F_DUPFD)
static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
{
@@ -328,7 +325,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
int ret;
-#ifdef QT_THREADSAFE_CLOEXEC
+#if QT_CONFIG(dup3)
// use dup3
QT_EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
return ret;
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 1b7a6537b05..fe54750303f 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -27,8 +27,16 @@ static constexpr bool UsingEventfd = true;
static constexpr bool UsingEventfd = false;
#endif
-#if defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
+# include "qbytearray.h"
+# include "qdatetime.h"
+# include "qdir.h" // to get application name
+# include "qrandom.h"
# include <pipeDrv.h>
+# include <selectLib.h>
+# include <taskLib.h>
+# include <rtpLib.h>
+# include <sysLib.h>
#endif
using namespace std::chrono;
@@ -62,12 +70,12 @@ QThreadPipe::~QThreadPipe()
if (!UsingEventfd && fds[1] >= 0)
close(fds[1]);
-#if defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
pipeDevDelete(name, true);
#endif
}
-#if defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -88,20 +96,32 @@ bool QThreadPipe::init()
{
#if defined(Q_OS_WASM)
// do nothing.
-#elif defined(Q_OS_VXWORKS)
- std::snprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
+#elif defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
+ RTP_DESC rtpStruct;
+ rtpInfoGet((RTP_ID)NULL, &rtpStruct);
+
+ QByteArray pipeName("/pipe/qevloop_");
+ QByteArray path(rtpStruct.pathName);
+ pipeName.append(path.mid(path.lastIndexOf(QDir::separator().toLatin1())+1, path.size()));
+ pipeName.append("_");
+ pipeName.append(QByteArray::number((uint)rtpStruct.entrAddr, 16));
+ pipeName.append("_");
+ pipeName.append(QByteArray::number((uint)QThread::currentThreadId(), 16));
+ pipeName.append("_");
+ QRandomGenerator rg(QTime::currentTime().msecsSinceStartOfDay());
+ pipeName.append(QByteArray::number(rg.generate()));
// make sure there is no pipe with this name
- pipeDevDelete(name, true);
+ pipeDevDelete(pipeName, true);
// create the pipe
- if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
- perror("QThreadPipe: Unable to create thread pipe device");
+ if (pipeDevCreate(pipeName, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
+ qCritical("QThreadPipe: Unable to create thread pipe device %s : %s", name, std::strerror(errno));
return false;
}
- if ((fds[0] = open(name, O_RDWR, 0)) < 0) {
- perror("QThreadPipe: Unable to open pipe device");
+ if ((fds[0] = open(pipeName, O_RDWR, 0)) < 0) {
+ qCritical("QThreadPipe: Unable to open pipe device %s : %s", name, std::strerror(errno));
return false;
}
@@ -150,7 +170,7 @@ int QThreadPipe::check(const pollfd &pfd)
if (readyread) {
// consume the data on the thread pipe so that
// poll doesn't immediately return next time
-#if defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
::read(fds[0], c, sizeof(c));
::ioctl(fds[0], FIOFLUSH, 0);
#else
diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h
index 7e85bc537b5..f53edc39655 100644
--- a/src/network/socket/qnet_unix_p.h
+++ b/src/network/socket/qnet_unix_p.h
@@ -73,7 +73,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
int fd;
-#ifdef QT_THREADSAFE_CLOEXEC
+#if QT_CONFIG(accept4)
// use accept4
int sockflags = SOCK_CLOEXEC;
if (flags & O_NONBLOCK)