+SystemcallPrivate::SystemcallPrivate(std::string const & sf,
+ std::string const & of,
+ std::string const & ef) :
+ process_(new QProcess),
+ out_index_(0),
+ err_index_(0),
+ in_file_(sf),
+ out_file_(of),
+ err_file_(ef),
+ process_events_(false)
+{
+ if (!in_file_.empty())
+ process_->setStandardInputFile(QString::fromLocal8Bit(in_file_.c_str()));
+ if (!out_file_.empty()) {
+ if (out_file_[0] == '&') {
+ if (subst(out_file_, " ", "") == "&2"
+ && err_file_[0] != '&') {
+ out_file_ = err_file_;
+ process_->setProcessChannelMode(
+ QProcess::MergedChannels);
+ } else {
+ if (err_file_[0] == '&') {
+ // Leave alone things such as
+ // "1>&2 2>&1". Should not be harmful,
+ // but let's give anyway a warning.
+ LYXERR0("Unsupported stdout/stderr redirect.");
+ err_file_.erase();
+ } else {
+ LYXERR0("Ambiguous stdout redirect: "
+ << out_file_);
+ }
+ out_file_ = os::nulldev();
+ }
+ }
+ // Check whether we have to set the output file.
+ if (out_file_ != os::nulldev()) {
+ process_->setStandardOutputFile(QString::fromLocal8Bit(
+ out_file_.c_str()));
+ }
+ }
+ if (!err_file_.empty()) {
+ if (err_file_[0] == '&') {
+ if (subst(err_file_, " ", "") == "&1"
+ && out_file_[0] != '&') {
+ process_->setProcessChannelMode(
+ QProcess::MergedChannels);
+ } else {
+ LYXERR0("Ambiguous stderr redirect: "
+ << err_file_);
+ }
+ // In MergedChannels mode stderr goes to stdout.
+ err_file_ = os::nulldev();
+ }
+ // Check whether we have to set the error file.
+ if (err_file_ != os::nulldev()) {
+ process_->setStandardErrorFile(QString::fromLocal8Bit(
+ err_file_.c_str()));
+ }
+ }
+
+ connect(process_, SIGNAL(readyReadStandardOutput()), SLOT(stdOut()));
+ connect(process_, SIGNAL(readyReadStandardError()), SLOT(stdErr()));
+#if QT_VERSION >= 0x050600
+ connect(process_, SIGNAL(errorOccurred(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError)));
+#else
+ connect(process_, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError)));
+#endif
+ connect(process_, SIGNAL(started()), this, SLOT(processStarted()));
+ connect(process_, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(processFinished(int, QProcess::ExitStatus)));
+}
+
+
+void SystemcallPrivate::startProcess(QString const & cmd, string const & path,
+ string const & lpath, bool detached)
+{
+ cmd_ = cmd;
+ if (detached) {
+ state = SystemcallPrivate::Running;
+ if (!QProcess::startDetached(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_)) {
+ state = SystemcallPrivate::Error;
+ return;
+ }
+ QProcess* released = releaseProcess();
+ delete released;
+ } else if (process_) {
+ state = SystemcallPrivate::Starting;
+ process_->start(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_);
+ }
+}
+
+
+void SystemcallPrivate::processEvents()
+{
+ if (process_events_) {
+ QCoreApplication::processEvents(/*QEventLoop::ExcludeUserInputEvents*/);
+ }
+}
+
+
+void SystemcallPrivate::waitAndProcessEvents()