From 5147f73ac301d9beeab2db402ed5cf42ad45ea4d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 17 Jun 2015 17:01:43 +0200 Subject: [PATCH] Core: Consolidate QProcess error reporting Introduce two methods to set set error and errorString, and optionally emit the error() signal. This also fixes two places where errorString hasn't been set previously. Change-Id: Ib7c27ff2daff898745e8e20ff8f11eaae568697f Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess.cpp | 69 ++++++++++++++++++++++--------- src/corelib/io/qprocess_p.h | 2 + src/corelib/io/qprocess_unix.cpp | 37 +++++------------ src/corelib/io/qprocess_win.cpp | 40 ++++++------------ src/corelib/io/qprocess_wince.cpp | 9 ++-- 5 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index da6e0c87af1..8f7f164f765 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -895,6 +895,48 @@ void QProcessPrivate::cleanup() #endif } +/*! + \internal +*/ +void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description) +{ + processError = error; + if (description.isEmpty()) { + switch (error) { + case QProcess::FailedToStart: + errorString = QProcess::tr("Process failed to start"); + case QProcess::Crashed: + errorString = QProcess::tr("Process crashed"); + break; + case QProcess::Timedout: + errorString = QProcess::tr("Process operation timed out"); + break; + case QProcess::ReadError: + errorString = QProcess::tr("Error reading from process"); + break; + case QProcess::WriteError: + errorString = QProcess::tr("Error writing to process"); + break; + case QProcess::UnknownError: + errorString.clear(); + break; + } + } else { + errorString = description; + } +} + +/*! + \internal +*/ +void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description) +{ + Q_Q(QProcess); + Q_ASSERT(error != QProcess::UnknownError); + setError(error, description); + emit q->error(processError); +} + /*! \internal Returns true if we emitted readyRead(). @@ -918,9 +960,7 @@ bool QProcessPrivate::tryReadFromChannel(Channel *channel) return false; } if (readBytes == -1) { - processError = QProcess::ReadError; - q->setErrorString(QProcess::tr("Error reading from process")); - emit q->error(processError); + setErrorAndEmit(QProcess::ReadError); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel); #endif @@ -1004,9 +1044,7 @@ bool QProcessPrivate::_q_canWrite() stdinChannel.buffer.nextDataBlockSize()); if (written < 0) { closeChannel(&stdinChannel); - processError = QProcess::WriteError; - q->setErrorString(QProcess::tr("Error writing to process")); - emit q->error(processError); + setErrorAndEmit(QProcess::WriteError); return false; } @@ -1075,9 +1113,7 @@ bool QProcessPrivate::_q_processDied() if (crashed) { exitStatus = QProcess::CrashExit; - processError = QProcess::Crashed; - q->setErrorString(QProcess::tr("Process crashed")); - emit q->error(processError); + setErrorAndEmit(QProcess::Crashed); } else { #ifdef QPROCESS_USE_SPAWN // if we're using posix_spawn, waitForStarted always succeeds. @@ -1085,8 +1121,8 @@ bool QProcessPrivate::_q_processDied() // 127 if anything prevents the target program from starting. // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html if (exitStatus == QProcess::NormalExit && exitCode == 127) { - processError = QProcess::FailedToStart; - q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)")); + setError(QProcess::FailedToStart, + QProcess::tr("Process failed to start (spawned process exited with code 127)")); } #endif } @@ -1130,8 +1166,7 @@ bool QProcessPrivate::_q_startupNotification() } q->setProcessState(QProcess::NotRunning); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart); #ifdef Q_OS_UNIX // make sure the process manager removes this entry waitForDeadChild(); @@ -1939,9 +1974,7 @@ qint64 QProcess::writeData(const char *data, qint64 len) #if defined(Q_OS_WINCE) Q_UNUSED(data); Q_UNUSED(len); - d->processError = QProcess::WriteError; - setErrorString(tr("Error writing to process")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::WriteError); return -1; #endif @@ -2220,9 +2253,7 @@ void QProcess::start(const QString &command, OpenMode mode) QStringList args = parseCombinedArgString(command); if (args.isEmpty()) { Q_D(QProcess); - d->processError = QProcess::FailedToStart; - setErrorString(tr("No program defined")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined")); return; } diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index f6bd64fb876..fc6b5345d15 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -383,6 +383,8 @@ public: qint64 writeToStdin(const char *data, qint64 maxlen); void cleanup(); + void setError(QProcess::ProcessError error, const QString &description = QString()); + void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString()); #ifdef Q_OS_BLACKBERRY QList defaultNotifiers() const; diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 5ea3bf8982c..47611d4b005 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -203,8 +203,8 @@ bool QProcessPrivate::openChannel(Channel &channel) channel.pipe[1] = -1; if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1) return true; // success - - q->setErrorString(QProcess::tr("Could not open input redirection for reading")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } else { int mode = O_WRONLY | O_CREAT; if (channel.append) @@ -216,12 +216,9 @@ bool QProcessPrivate::openChannel(Channel &channel) if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1) return true; // success - q->setErrorString(QProcess::tr("Could not open output redirection for writing")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } - - // could not open file - processError = QProcess::FailedToStart; - emit q->error(processError); cleanup(); return false; } else { @@ -330,9 +327,7 @@ void QProcessPrivate::startProcess() !openChannel(stdoutChannel) || !openChannel(stderrChannel) || qt_create_pipe(childStartedPipe) != 0) { - processError = QProcess::FailedToStart; - q->setErrorString(qt_error_string(errno)); - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, qt_error_string(errno)); cleanup(); return; } @@ -458,9 +453,8 @@ void QProcessPrivate::startProcess() qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno))); #endif q->setProcessState(QProcess::NotRunning); - processError = QProcess::FailedToStart; - q->setErrorString(QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno))); - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno))); cleanup(); return; } @@ -808,8 +802,6 @@ void QProcessPrivate::killProcess() bool QProcessPrivate::waitForStarted(int msecs) { - Q_Q(QProcess); - #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs, childStartedPipe[0]); @@ -819,8 +811,7 @@ bool QProcessPrivate::waitForStarted(int msecs) FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs); #endif @@ -847,7 +838,6 @@ QList QProcessPrivate::defaultNotifiers() const bool QProcessPrivate::waitForReadyRead(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs); #endif @@ -890,8 +880,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) break; } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -927,7 +916,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs) bool QProcessPrivate::waitForBytesWritten(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs); #endif @@ -972,8 +960,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -1002,7 +989,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) bool QProcessPrivate::waitForFinished(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif @@ -1046,8 +1032,7 @@ bool QProcessPrivate::waitForFinished(int msecs) break; } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 8bbca203657..5c9db05efff 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -217,7 +217,8 @@ bool QProcessPrivate::openChannel(Channel &channel) if (channel.pipe[0] != INVALID_Q_PIPE) return true; - q->setErrorString(QProcess::tr("Could not open input redirection for reading")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } else { // open in write mode channel.pipe[0] = INVALID_Q_PIPE; @@ -237,12 +238,9 @@ bool QProcessPrivate::openChannel(Channel &channel) return true; } - q->setErrorString(QProcess::tr("Could not open output redirection for writing")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open output redirection for writing")); } - - // could not open file - processError = QProcess::FailedToStart; - emit q->error(processError); cleanup(); return false; } else { @@ -504,9 +502,10 @@ void QProcessPrivate::startProcess() environment.isEmpty() ? 0 : envlist.data(), workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(), &startupInfo, pid); + QString errorString; if (!success) { // Capture the error string before we do CloseHandle below - q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string())); + errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string()); } if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { @@ -524,8 +523,7 @@ void QProcessPrivate::startProcess() if (!success) { cleanup(); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, errorString); q->setProcessState(QProcess::NotRunning); return; } @@ -595,16 +593,13 @@ void QProcessPrivate::killProcess() bool QProcessPrivate::waitForStarted(int) { - Q_Q(QProcess); - if (processStarted()) return true; if (processError == QProcess::FailedToStart) return false; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -636,8 +631,6 @@ bool QProcessPrivate::drainOutputPipes() bool QProcessPrivate::waitForReadyRead(int msecs) { - Q_Q(QProcess); - QIncrementalSleepTimer timer(msecs); forever { @@ -663,15 +656,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } bool QProcessPrivate::waitForBytesWritten(int msecs) { - Q_Q(QProcess); - QIncrementalSleepTimer timer(msecs); forever { @@ -731,14 +721,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } bool QProcessPrivate::waitForFinished(int msecs) { - Q_Q(QProcess); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif @@ -770,8 +758,7 @@ bool QProcessPrivate::waitForFinished(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -814,13 +801,10 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) bool QProcessPrivate::waitForWrite(int msecs) { - Q_Q(QProcess); - if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs)) return true; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 53767758c27..807472b7b20 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -138,8 +138,7 @@ void QProcessPrivate::startProcess() if (!success) { cleanup(); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart); q->setProcessState(QProcess::NotRunning); return; } @@ -210,8 +209,7 @@ bool QProcessPrivate::waitForStarted(int) if (processError == QProcess::FailedToStart) return false; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -251,8 +249,7 @@ bool QProcessPrivate::waitForFinished(int msecs) if (timer.hasTimedOut()) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; }