?? qprocess_unix.cpp
字號(hào):
static int qt_native_select(fd_set *fdread, fd_set *fdwrite, int timeout){ struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; int ret; do { ret = select(FD_SETSIZE, fdread, fdwrite, 0, timeout < 0 ? 0 : &tv); } while (ret < 0 && (errno == EINTR)); return ret;}/* Returns the difference between msecs and elapsed. If msecs is -1, however, -1 is returned.*/static int qt_timeout_value(int msecs, int elapsed){ if (msecs == -1) return -1; int timeout = msecs - elapsed; return timeout < 0 ? 0 : timeout;}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]);#endif fd_set fds; FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); int ret; do { ret = qt_native_select(&fds, 0, msecs); } while (ret < 0 && errno == EINTR); if (ret == 0) { processError = QProcess::Timedout; q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Process operation timed out")));#if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs);#endif return false; } bool startedEmitted = _q_startupNotification();#if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted() == %s", startedEmitted ? "true" : "false");#endif return startedEmitted;}bool QProcessPrivate::waitForReadyRead(int msecs){ Q_Q(QProcess);#if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs);#endif QTime stopWatch; stopWatch.start(); forever { fd_set fdread; fd_set fdwrite; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) FD_SET(childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) FD_SET(stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) FD_SET(stderrChannel.pipe[0], &fdread); FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); int ret = qt_native_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; break; } if (ret == 0) { processError = QProcess::Timedout; q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Process operation timed out"))); return false; } if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { if (!_q_startupNotification()) return false; } bool readyReadEmitted = false; if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) { bool canRead = _q_canReadStandardOutput(); if (processChannel == QProcess::StandardOutput && canRead) readyReadEmitted = true; } if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) { bool canRead = _q_canReadStandardError(); if (processChannel == QProcess::StandardError && canRead) readyReadEmitted = true; } if (readyReadEmitted) return true; if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) _q_canWrite(); if (FD_ISSET(deathPipe[0], &fdread)) { if (_q_processDied()) return false; } } return false;}bool QProcessPrivate::waitForBytesWritten(int msecs){ Q_Q(QProcess);#if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs);#endif QTime stopWatch; stopWatch.start(); while (!writeBuffer.isEmpty()) { fd_set fdread; fd_set fdwrite; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) FD_SET(childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) FD_SET(stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) FD_SET(stderrChannel.pipe[0], &fdread); FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); int ret = qt_native_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; break; } if (ret == 0) { processError = QProcess::Timedout; q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Process operation timed out"))); return false; } if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { if (!_q_startupNotification()) return false; } if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) return _q_canWrite(); if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) _q_canReadStandardOutput(); if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) _q_canReadStandardError(); if (FD_ISSET(deathPipe[0], &fdread)) { if (_q_processDied()) return false; } } return false;}bool QProcessPrivate::waitForFinished(int msecs){ Q_Q(QProcess);#if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForFinished(%d)", msecs);#endif QTime stopWatch; stopWatch.start(); forever { fd_set fdread; fd_set fdwrite; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) FD_SET(childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) FD_SET(stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) FD_SET(stderrChannel.pipe[0], &fdread); if (processState == QProcess::Running) FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); int ret = qt_native_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; break; } if (ret == 0) { processError = QProcess::Timedout; q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Process operation timed out"))); return false; } if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { if (!_q_startupNotification()) return false; } if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) _q_canWrite(); if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) _q_canReadStandardOutput(); if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) _q_canReadStandardError(); if (FD_ISSET(deathPipe[0], &fdread)) { if (_q_processDied()) return true; } } return false;}bool QProcessPrivate::waitForWrite(int msecs){ fd_set fdwrite; FD_ZERO(&fdwrite); FD_SET(stdinChannel.pipe[1], &fdwrite); int ret; do { ret = qt_native_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } while (ret < 0 && errno == EINTR); return ret == 1;}void QProcessPrivate::findExitCode(){ Q_Q(QProcess); processManager()->remove(q);}bool QProcessPrivate::waitForDeadChild(){ Q_Q(QProcess); // read a byte from the death pipe char c; qt_native_read(deathPipe[0], &c, 1); // check if our process is dead int exitStatus; pid_t waitResult = waitpid(pid_t(pid), &exitStatus, WNOHANG); if (waitResult > 0) { processManager()->remove(q); crashed = !WIFEXITED(exitStatus); exitCode = WEXITSTATUS(exitStatus);#if defined QPROCESS_DEBUG qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode" << exitCode << ", crashed?" << crashed;#endif return true; }#if defined QPROCESS_DEBUG qDebug() << "QProcessPrivate::waitForDeadChild() not dead!";#endif return false;}void QProcessPrivate::_q_notified(){}/*! \internal */bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments){ processManager()->start(); // To catch the startup of the child int startedPipe[2]; ::pipe(startedPipe); pid_t childPid = fork(); if (childPid == 0) { ::setsid(); ::signal(SIGHUP, SIG_IGN); qt_native_close(startedPipe[0]); ::signal(SIGPIPE, SIG_DFL); pid_t doubleForkPid = fork(); if (doubleForkPid == 0) { ::fcntl(startedPipe[1], F_SETFD, FD_CLOEXEC); char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) {#ifdef Q_OS_MAC argv[i + 1] = ::strdup(arguments.at(i).toUtf8().constData());#else argv[i + 1] = ::strdup(arguments.at(i).toLocal8Bit().constData());#endif } argv[arguments.size() + 1] = 0; if (!program.contains(QLatin1Char('/'))) { const QString path = QString::fromLocal8Bit(::getenv("PATH")); if (!path.isEmpty()) { QStringList pathEntries = path.split(QLatin1Char(':')); for (int k = 0; k < pathEntries.size(); ++k) { QByteArray tmp = QFile::encodeName(pathEntries.at(k)); if (!tmp.endsWith('/')) tmp += '/'; tmp += QFile::encodeName(program); argv[0] = tmp.data(); qt_native_execv(argv[0], argv); } } } else { QByteArray tmp = QFile::encodeName(program); argv[0] = tmp.data(); qt_native_execv(argv[0], argv); } struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; qt_native_sigaction(SIGPIPE, &noaction, 0); // '\1' means execv failed char c = '\1'; qt_native_write(startedPipe[1], &c, 1); qt_native_close(startedPipe[1]); ::_exit(1); } else if (doubleForkPid == -1) { struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; qt_native_sigaction(SIGPIPE, &noaction, 0); // '\2' means internal error char c = '\2'; qt_native_write(startedPipe[1], &c, 1); } qt_native_close(startedPipe[1]); qt_native_chdir("/"); ::_exit(1); } qt_native_close(startedPipe[1]); if (childPid == -1) { qt_native_close(startedPipe[0]); return false; } char reply = '\0'; int startResult = qt_native_read(startedPipe[0], &reply, 1); int result; qt_native_close(startedPipe[0]); ::waitpid(childPid, &result, 0); return startResult != -1 && reply == '\0';}void QProcessPrivate::initializeProcessManager(){ (void) processManager();}#include "qprocess_unix.moc"#endif // QT_NO_PROCESS
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -