From f03e9164c010cfaf125db4fd0c9792e793715298 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 22 May 2021 16:53:41 +0300 Subject: QProcess: untangle platform-specific details - add missing #ifdef in header file; - split some functions (writeData(), _q_canWrite(), cleanup()) into their platform-specific implementations. Change-Id: I4e7c1c377ec8468ed120d38acf2543eef9316c01 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess.cpp | 117 --------------------------------------- src/corelib/io/qprocess_p.h | 8 +-- src/corelib/io/qprocess_unix.cpp | 61 ++++++++++++++++++++ src/corelib/io/qprocess_win.cpp | 69 ++++++++++++++++++++++- 4 files changed, 131 insertions(+), 124 deletions(-) (limited to 'src/corelib/io') diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index d5c2c8980b..0702667042 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -41,12 +41,8 @@ //#define QPROCESS_DEBUG #include -#include #include #include -#if defined(Q_OS_WIN) -#include -#endif #include "qprocess.h" #include "qprocess_p.h" @@ -54,15 +50,8 @@ #include #include #include -#include #include -#ifdef Q_OS_WIN -#include -#else -#include -#endif - #if __has_include() #include #endif @@ -807,44 +796,6 @@ QProcessPrivate::~QProcessPrivate() stdoutChannel.process->stdinChannel.clear(); } -/*! - \internal -*/ -void QProcessPrivate::cleanup() -{ - q_func()->setProcessState(QProcess::NotRunning); -#ifdef Q_OS_WIN - if (stdinWriteTrigger) { - delete stdinWriteTrigger; - stdinWriteTrigger = 0; - } - if (processFinishedNotifier) { - delete processFinishedNotifier; - processFinishedNotifier = 0; - } - if (pid) { - CloseHandle(pid->hThread); - CloseHandle(pid->hProcess); - delete pid; - pid = nullptr; - } -#else - pid = 0; -#endif - - if (stateNotifier) { - delete stateNotifier; - stateNotifier = nullptr; - } - closeChannels(); - destroyPipe(childStartedPipe); -#ifdef Q_OS_UNIX - if (forkfd != -1) - qt_safe_close(forkfd); - forkfd = -1; -#endif -} - /*! \internal */ @@ -1064,36 +1015,6 @@ bool QProcessPrivate::_q_canReadStandardError() return tryReadFromChannel(&stderrChannel); } -/*! - \internal -*/ -bool QProcessPrivate::_q_canWrite() -{ - if (writeBuffer.isEmpty()) { -#ifdef Q_OS_WIN - if (stdinChannel.closed && pipeWriterBytesToWrite() == 0) - closeWriteChannel(); -#else - if (stdinChannel.notifier) - stdinChannel.notifier->setEnabled(false); -#endif -#if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer)."); -#endif - return false; - } - - const bool writeSucceeded = writeToStdin(); - -#ifdef Q_OS_UNIX - if (writeBuffer.isEmpty() && stdinChannel.closed) - closeWriteChannel(); - else if (stdinChannel.notifier) - stdinChannel.notifier->setEnabled(!writeBuffer.isEmpty()); -#endif - return writeSucceeded; -} - /*! \internal */ @@ -1905,44 +1826,6 @@ qint64 QProcess::readData(char *data, qint64 maxlen) return 0; } -/*! \reimp -*/ -qint64 QProcess::writeData(const char *data, qint64 len) -{ - Q_D(QProcess); - - if (d->stdinChannel.closed) { -#if defined QPROCESS_DEBUG - qDebug("QProcess::writeData(%p \"%s\", %lld) == 0 (write channel closing)", - data, QtDebugUtils::toPrintable(data, len, 16).constData(), len); -#endif - return 0; - } - -#if defined(Q_OS_WIN) - if (!d->stdinWriteTrigger) { - d->stdinWriteTrigger = new QTimer; - d->stdinWriteTrigger->setSingleShot(true); - QObjectPrivate::connect(d->stdinWriteTrigger, &QTimer::timeout, - d, &QProcessPrivate::_q_canWrite); - } -#endif - - d->write(data, len); -#ifdef Q_OS_WIN - if (!d->stdinWriteTrigger->isActive()) - d->stdinWriteTrigger->start(); -#else - if (d->stdinChannel.notifier) - d->stdinChannel.notifier->setEnabled(true); -#endif -#if defined QPROCESS_DEBUG - qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)", - data, QtDebugUtils::toPrintable(data, len, 16).constData(), len, len); -#endif - return len; -} - /*! Regardless of the current read channel, this function returns all data available from the standard output of the process as a diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 78bbe01cf2..078c617021 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -330,14 +330,11 @@ public: #endif QProcessEnvironment environment; +#ifdef Q_OS_UNIX Q_PIPE childStartedPipe[2] = {INVALID_Q_PIPE, INVALID_Q_PIPE}; - void destroyPipe(Q_PIPE pipe[2]); - QSocketNotifier *stateNotifier = nullptr; - int forkfd = -1; - -#ifdef Q_OS_WIN +#else QTimer *stdinWriteTrigger = nullptr; QWinEventNotifier *processFinishedNotifier = nullptr; #endif @@ -378,6 +375,7 @@ public: qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen); bool writeToStdin(); + void destroyPipe(Q_PIPE pipe[2]); void cleanup(); void setError(QProcess::ProcessError error, const QString &description = QString()); void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString()); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index d31691d950..bf19fc2183 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -276,6 +276,21 @@ void QProcessPrivate::closeChannel(Channel *channel) destroyPipe(channel->pipe); } +void QProcessPrivate::cleanup() +{ + q_func()->setProcessState(QProcess::NotRunning); + + closeChannels(); + delete stateNotifier; + stateNotifier = nullptr; + destroyPipe(childStartedPipe); + pid = 0; + if (forkfd != -1) { + qt_safe_close(forkfd); + forkfd = -1; + } +} + /* Create the pipes to a QProcessPrivate::Channel. */ @@ -642,6 +657,52 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint return bytesRead; } +/*! \reimp +*/ +qint64 QProcess::writeData(const char *data, qint64 len) +{ + Q_D(QProcess); + + if (d->stdinChannel.closed) { +#if defined QPROCESS_DEBUG + qDebug("QProcess::writeData(%p \"%s\", %lld) == 0 (write channel closing)", + data, QtDebugUtils::toPrintable(data, len, 16).constData(), len); +#endif + return 0; + } + + d->write(data, len); + if (d->stdinChannel.notifier) + d->stdinChannel.notifier->setEnabled(true); + +#if defined QPROCESS_DEBUG + qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)", + data, QtDebugUtils::toPrintable(data, len, 16).constData(), len, len); +#endif + return len; +} + +bool QProcessPrivate::_q_canWrite() +{ + if (writeBuffer.isEmpty()) { + if (stdinChannel.notifier) + stdinChannel.notifier->setEnabled(false); +#if defined QPROCESS_DEBUG + qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer)."); +#endif + return false; + } + + const bool writeSucceeded = writeToStdin(); + + if (writeBuffer.isEmpty() && stdinChannel.closed) + closeWriteChannel(); + else if (stdinChannel.notifier) + stdinChannel.notifier->setEnabled(!writeBuffer.isEmpty()); + + return writeSucceeded; +} + bool QProcessPrivate::writeToStdin() { const char *data = writeBuffer.readPointer(); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 24a6e2109c..65422659b0 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -39,6 +39,9 @@ ****************************************************************************/ //#define QPROCESS_DEBUG +#include +#include + #include "qprocess.h" #include "qprocess_p.h" #include "qwindowspipereader_p.h" @@ -50,9 +53,9 @@ #include #include #include +#include #include #include -#include #include "private/qfsfileengine_p.h" // for longFileName @@ -375,6 +378,23 @@ void QProcessPrivate::closeChannel(Channel *channel) destroyPipe(channel->pipe); } +void QProcessPrivate::cleanup() +{ + q_func()->setProcessState(QProcess::NotRunning); + + closeChannels(); + delete stdinWriteTrigger; + stdinWriteTrigger = nullptr; + delete processFinishedNotifier; + processFinishedNotifier = nullptr; + if (pid) { + CloseHandle(pid->hThread); + CloseHandle(pid->hProcess); + delete pid; + pid = nullptr; + } +} + static QString qt_create_commandline(const QString &program, const QStringList &arguments, const QString &nativeArguments) { @@ -816,7 +836,6 @@ bool QProcessPrivate::waitForFinished(const QDeadlineTimer &deadline) return false; } - void QProcessPrivate::findExitCode() { DWORD theExitCode; @@ -828,6 +847,38 @@ void QProcessPrivate::findExitCode() } } +/*! \reimp +*/ +qint64 QProcess::writeData(const char *data, qint64 len) +{ + Q_D(QProcess); + + if (d->stdinChannel.closed) { +#if defined QPROCESS_DEBUG + qDebug("QProcess::writeData(%p \"%s\", %lld) == 0 (write channel closing)", + data, QtDebugUtils::toPrintable(data, len, 16).constData(), len); +#endif + return 0; + } + + if (!d->stdinWriteTrigger) { + d->stdinWriteTrigger = new QTimer; + d->stdinWriteTrigger->setSingleShot(true); + QObjectPrivate::connect(d->stdinWriteTrigger, &QTimer::timeout, + d, &QProcessPrivate::_q_canWrite); + } + + d->write(data, len); + if (!d->stdinWriteTrigger->isActive()) + d->stdinWriteTrigger->start(); + +#if defined QPROCESS_DEBUG + qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)", + data, QtDebugUtils::toPrintable(data, len, 16).constData(), len, len); +#endif + return len; +} + qint64 QProcessPrivate::pipeWriterBytesToWrite() const { return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0); @@ -844,6 +895,20 @@ void QProcessPrivate::_q_bytesWritten(qint64 bytes) _q_canWrite(); } +bool QProcessPrivate::_q_canWrite() +{ + if (writeBuffer.isEmpty()) { + if (stdinChannel.closed && pipeWriterBytesToWrite() == 0) + closeWriteChannel(); +#if defined QPROCESS_DEBUG + qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer)."); +#endif + return false; + } + + return writeToStdin(); +} + bool QProcessPrivate::writeToStdin() { Q_Q(QProcess); -- cgit v1.2.3