📄 qprocess.cpp
字号:
char *ptr = errorReadBuffer.reserve(available); qint64 readBytes = readFromStderr(ptr, available); if (readBytes == -1) { processError = QProcess::ReadError; q->setErrorString(QT_TRANSLATE_NOOP(QProcess, QLatin1String("Error reading from process"))); emit q->error(processError); return false; } if (standardErrorClosed) { errorReadBuffer.truncate(readBytes); return false; } errorReadBuffer.truncate(available - readBytes); bool didRead = false; if (readBytes == 0) { if (errorReadSocketNotifier) errorReadSocketNotifier->setEnabled(false); } else if (processChannel == QProcess::StandardError) { didRead = true; if (!emittedReadyRead) { emittedReadyRead = true; emit q->readyRead(); emittedReadyRead = false; } } emit q->readyReadStandardError(); return didRead;}/*! \internal*/bool QProcessPrivate::_q_canWrite(){ Q_Q(QProcess);#if defined QPROCESS_DEBUG qDebug("QProcessPrivate::_q_canWrite()");#endif if (writeSocketNotifier) writeSocketNotifier->setEnabled(false); if (writeBuffer.isEmpty()) return false; qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); if (written < 0) { destroyPipe(writePipe); processError = QProcess::WriteError; q->setErrorString(QT_TRANSLATE_NOOP(QProcess, QLatin1String("Error writing to process"))); emit q->error(processError); return false; } writeBuffer.free(written); if (!emittedBytesWritten) { emittedBytesWritten = true; emit q->bytesWritten(written); emittedBytesWritten = false; } if (writeSocketNotifier && !writeBuffer.isEmpty()) writeSocketNotifier->setEnabled(true); if (writeBuffer.isEmpty() && writeChannelClosing) closeWriteChannel(); return true;}/*! \internal*/bool QProcessPrivate::_q_processDied(){ Q_Q(QProcess);#if defined QPROCESS_DEBUG qDebug("QProcessPrivate::_q_processDied()");#endif#ifdef Q_OS_UNIX if (!waitForDeadChild()) return false;#endif#ifdef Q_OS_WIN if (processFinishedNotifier) processFinishedNotifier->setEnabled(false);#endif // the process may have died before it got a chance to report that it was // either running or stopped, so we will call _q_startupNotification() and // give it a chance to emit started() or error(FailedToStart). if (processState == QProcess::Starting) { if (!_q_startupNotification()) return true; } // in case there is data in the pipe line and this slot by chance // got called before the read notifications, call these two slots // so the data is made available before the process dies. _q_canReadStandardOutput(); _q_canReadStandardError(); findExitCode(); if (crashed) { exitStatus = QProcess::CrashExit; processError = QProcess::Crashed; q->setErrorString(QT_TRANSLATE_NOOP(QProcess, QLatin1String("Process crashed"))); emit q->error(processError); } cleanup(); processState = QProcess::NotRunning; emit q->stateChanged(processState); emit q->finished(exitCode); emit q->finished(exitCode, exitStatus);#if defined QPROCESS_DEBUG qDebug("QProcessPrivate::_q_processDied() process is dead");#endif return true;}/*! \internal*/bool QProcessPrivate::_q_startupNotification(){ Q_Q(QProcess);#if defined QPROCESS_DEBUG qDebug("QProcessPrivate::startupNotification()");#endif if (startupSocketNotifier) startupSocketNotifier->setEnabled(false); if (processStarted()) { processState = QProcess::Running; emit q->started(); return true; } processState = QProcess::NotRunning; processError = QProcess::FailedToStart; emit q->error(processError);#ifdef Q_OS_UNIX // make sure the process manager removes this entry waitForDeadChild(); findExitCode();#endif cleanup(); return false;}/*! \internal*/void QProcessPrivate::closeWriteChannel(){#if defined QPROCESS_DEBUG qDebug("QProcessPrivate::closeWriteChannel()");#endif if (writeSocketNotifier) { writeSocketNotifier->setEnabled(false); delete writeSocketNotifier; writeSocketNotifier = 0; } destroyPipe(writePipe);}/*! Constructs a QProcess object with the given \a parent.*/QProcess::QProcess(QObject *parent) : QIODevice(*new QProcessPrivate, parent){#if defined QPROCESS_DEBUG qDebug("QProcess::QProcess(%p)", parent);#endif}/*! Destructs the QProcess object.*/QProcess::~QProcess(){ Q_D(QProcess); if (d->processState != NotRunning) { qWarning("QProcess object destroyed while process is still running."); kill(); waitForFinished(); }#ifdef Q_OS_UNIX // make sure the process manager removes this entry d->findExitCode();#endif d->cleanup();}/*! Returns the read channel mode of the QProcess. \sa setReadChannelMode(), ProcessChannelMode, setReadChannel()*/QProcess::ProcessChannelMode QProcess::readChannelMode() const{ Q_D(const QProcess); return d->processChannelMode;}/*! Sets the read channel mode of the QProcess to the \a mode specified. This mode will be used the next time start() is called. For example: \code QProcess builder; builder.setReadChannelMode(QProcess::MergedChannels); builder.start("make", QStringList() << "-j2"); if (!builder.waitForFinished()) qDebug() << "Make failed:" << builder.errorString(); else qDebug() << "Make output:" << builder.readAll(); \endcode \sa readChannelMode(), ProcessChannelMode, setReadChannel()*/void QProcess::setReadChannelMode(ProcessChannelMode mode){ Q_D(QProcess); d->processChannelMode = mode;}/*! Returns the current read channel of the QProcess. \sa setReadChannel()*/QProcess::ProcessChannel QProcess::readChannel() const{ Q_D(const QProcess); return d->processChannel;}/*! Sets the current read channel of the QProcess to the given \a channel. The current input channel is used by the functions read(), readAll(), readLine(), and getChar(). It also determines which channel triggers QProcess to emit readyRead(). Changing the read channel will clear the unget buffer. \sa readChannel()*/void QProcess::setReadChannel(ProcessChannel channel){ Q_D(QProcess); if (d->processChannel != channel) d->ungetBuffer.clear(); d->processChannel = channel;}/*! Closes the read channel \a channel. After calling this function, QProcess will no longer receive data on the channel. Any data that has already been received is still available for reading. Call this function to save memory, if you are not interested in the output of the process. \sa closeWriteChannel(), setReadChannel()*/void QProcess::closeReadChannel(ProcessChannel channel){ Q_D(QProcess); if (channel == StandardOutput) d->standardOutputClosed = true; else d->standardErrorClosed = true;}/*! Schedules the write channel of QProcess to be closed. The channel will close once all data has been written to the process. After calling this function, any attempts to write to the process will fail. Closing the write channel is necessary for programs that read input data until the channel has been closed. For example, the program "more" is used to display text data in a console on both Unix and Windows. But it will not display the text data until QProcess's write channel has been closed. Example: \code QProcess more; more.start("more"); more.write("Text to display"); more.closeWriteChannel(); // QProcess will emit readyRead() once "more" starts printing \endcode The write channel is implicitly opened when start() is called. \sa closeReadChannel()*/void QProcess::closeWriteChannel(){ Q_D(QProcess); d->writeChannelClosing = true; if (d->writeBuffer.isEmpty()) d->closeWriteChannel();}/*! Returns the working directory that the QProcess will enter before the program has started. \sa setWorkingDirectory()*/QString QProcess::workingDirectory() const{ Q_D(const QProcess); return d->workingDirectory;}/*! Sets the working directory to \a dir. QProcess will start the process in this directory. The default behavior is to start the process in the working directory of the calling process. \sa workingDirectory(), start()*/void QProcess::setWorkingDirectory(const QString &dir){ Q_D(QProcess); d->workingDirectory = dir;}/*! Returns the native process identifier for the running process, if available. If no process is currently running, 0 is returned.*/Q_PID QProcess::pid() const{ Q_D(const QProcess); return d->pid;}/*! \reimp This function operates on the current read channel. \sa readChannel(), setReadChannel()*/bool QProcess::canReadLine() const{ Q_D(const QProcess); const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError) ? &d->errorReadBuffer : &d->outputReadBuffer; return readBuffer->canReadLine();}/*! Closes all communication with the process. After calling this function, QProcess will no longer emit readyRead(), and data can no longer be read or written.*/void QProcess::close(){ emit aboutToClose(); while (waitForBytesWritten(-1)) ; kill(); waitForFinished(-1); setOpenMode(QIODevice::NotOpen);}/*! \reimp Returns true if the process is not running, and no more data is available for reading; otherwise returns false.*/bool QProcess::atEnd() const{ Q_D(const QProcess); const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError) ? &d->errorReadBuffer : &d->outputReadBuffer; return !isOpen() || readBuffer->isEmpty();}/*! \reimp*/bool QProcess::isSequential() const{ return true;}/*! \reimp*/qint64 QProcess::bytesAvailable() const{ Q_D(const QProcess); const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError) ? &d->errorReadBuffer : &d->outputReadBuffer;#if defined QPROCESS_DEBUG qDebug("QProcess::bytesAvailable() == %i (%s)", readBuffer->size(), (d->processChannel == QProcess::StandardError) ? "stderr" : "stdout");#endif return readBuffer->size() + QIODevice::bytesAvailable();}/*! \reimp*/qint64 QProcess::bytesToWrite() const{ Q_D(const QProcess); return d->writeBuffer.size();}/*! Returns the type of error that occurred last. \sa state()*/QProcess::ProcessError QProcess::error() const{ Q_D(const QProcess); return d->processError;}/*! Returns the current state of the process. \sa stateChanged(), error()*/QProcess::ProcessState QProcess::state() const{ Q_D(const QProcess); return d->processState;}/*! Sets the environment that QProcess will use when starting a process to \a environment. \a environment is a list of key=value pairs. Example: \code QProcess process; QStringList env = QProcess::systemEnvironment(); env << "TMPDIR=C:\\MyApp\\temp"; // Add an environment variable env.replaceInStrings(QRegExp("^PATH=(.*)", false), "PATH=\\1;C:\\Bin"); // Add Bin to PATH process.setEnvironment(env); process.start("myapp"); \endcode \sa environment(), systemEnvironment()*/void QProcess::setEnvironment(const QStringList &environment){ Q_D(QProcess); d->environment = environment;}/*! Returns the environment that QProcess will use when starting a process, or an empty QStringList if no environment has been set using setEnvironment(). If no environment has been set, the environment of the calling process will be used. \sa setEnvironment(), systemEnvironment()*/QStringList QProcess::environment() const{ Q_D(const QProcess); return d->environment;}/*! Blocks until the process has started and the started() signal has been emitted, or until \a msecs milliseconds have passed. Returns true if the process was started successfully; otherwise returns false (if the operation timed out or if an error occurred). This function can operate without an event loop. It is useful when writing non-GUI applications and when performing I/O operations in a non-GUI thread. \warning Calling this function from the main (GUI) thread might cause your user interface to freeze. If msecs is -1, this function will not time out. \sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished()*/bool QProcess::waitForStarted(int msecs){ Q_D(QProcess); if (d->processState == QProcess::Starting) { if (!d->waitForStarted(msecs)) return false; d->processState = QProcess::Running; emit started(); } return d->processState == QProcess::Running;}/*! \reimp*/bool QProcess::waitForReadyRead(int msecs){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -