diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2021-05-22 16:53:41 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2021-06-04 14:50:47 +0300 |
commit | f03e9164c010cfaf125db4fd0c9792e793715298 (patch) | |
tree | a01b25133f2c2c410d08dd6e36b1a02a5830b8f0 /src/corelib/io | |
parent | 467b39d52c9ab59b1e7518330fbb51d5543ada50 (diff) |
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 <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qprocess.cpp | 117 | ||||
-rw-r--r-- | src/corelib/io/qprocess_p.h | 8 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 61 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 69 |
4 files changed, 131 insertions, 124 deletions
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 <qdebug.h> -#include <private/qdebug_p.h> #include <qdir.h> #include <qscopedvaluerollback.h> -#if defined(Q_OS_WIN) -#include <qtimer.h> -#endif #include "qprocess.h" #include "qprocess_p.h" @@ -54,15 +50,8 @@ #include <qbytearray.h> #include <qdeadlinetimer.h> #include <qcoreapplication.h> -#include <qsocketnotifier.h> #include <qtimer.h> -#ifdef Q_OS_WIN -#include <qwineventnotifier.h> -#else -#include <private/qcore_unix_p.h> -#endif - #if __has_include(<paths.h>) #include <paths.h> #endif @@ -810,44 +799,6 @@ QProcessPrivate::~QProcessPrivate() /*! \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 -*/ void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description) { processError = error; @@ -1067,36 +1018,6 @@ bool QProcessPrivate::_q_canReadStandardError() /*! \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 -*/ void QProcessPrivate::_q_processDied() { #if defined QPROCESS_DEBUG @@ -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 <qdebug.h> +#include <private/qdebug_p.h> + #include "qprocess.h" #include "qprocess_p.h" #include "qwindowspipereader_p.h" @@ -50,9 +53,9 @@ #include <qrandom.h> #include <qwineventnotifier.h> #include <qscopedvaluerollback.h> +#include <qtimer.h> #include <private/qsystemlibrary_p.h> #include <private/qthread_p.h> -#include <qdebug.h> #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); |