diff options
author | Karim Pinter <[email protected]> | 2025-05-02 16:13:38 +0300 |
---|---|---|
committer | Karim Pinter <[email protected]> | 2025-05-12 12:35:00 +0300 |
commit | 53756dcfbcb717327e26ee65cea995c2794e01fe (patch) | |
tree | bb6882573d066299b578a3ed2e3fe58ce41ea4ac | |
parent | 5ff542493dba52934d92f86463395e33b874906e (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.cmake | 53 | ||||
-rw-r--r-- | src/corelib/global/qconfig-bootstrapped.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_unix_p.h | 5 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 42 | ||||
-rw-r--r-- | src/network/socket/qnet_unix_p.h | 2 |
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) |