Take into account output redirection when spawning a program.

Now things should behave as before the QProcess era (I hope).
The parser only accounts for output redirection, no fancy
things such as piping are possible, yet.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29656 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2009-05-13 18:29:58 +00:00
parent 0ed38ed1f4
commit 70696182dd

View File

@ -14,6 +14,7 @@
#include <config.h>
#include "support/debug.h"
#include "support/lstrings.h"
#include "support/qstring_helpers.h"
#include "support/Systemcall.h"
#include "support/os.h"
@ -40,9 +41,9 @@ static void killProcess(QProcess * p)
// Reuse of instance
#ifndef USE_QPROCESS
int Systemcall::startscript(Starttype how, string const & what)
{
#ifndef USE_QPROCESS
string command = what;
if (how == DontWait) {
@ -57,14 +58,49 @@ int Systemcall::startscript(Starttype how, string const & what)
}
return ::system(command.c_str());
}
#else
QString cmd = QString::fromLocal8Bit(what.c_str());
namespace {
string const parsecmd(string const & cmd, string & outfile)
{
bool inquote = false;
bool escaped = false;
for (size_t i = 0; i < cmd.length(); ++i) {
char c = cmd[i];
if (c == '"' && !escaped)
inquote = !inquote;
else if (c == '\\' && !escaped)
escaped = !escaped;
else if (c == '>' && !(inquote || escaped)) {
outfile = trim(cmd.substr(i + 1), " \"");
return trim(cmd.substr(0, i));
} else
escaped = false;
}
outfile.erase();
return cmd;
}
} // namespace anon
int Systemcall::startscript(Starttype how, string const & what)
{
string outfile;
QString cmd = toqstr(parsecmd(what, outfile));
QProcess * process = new QProcess;
// Qt won't start the process if we redirect stdout/stderr in
// this way and they are not connected to a terminal (maybe
// because we were launched from some desktop GUI).
if (os::is_terminal(os::STDOUT))
if (!outfile.empty())
process->setStandardOutputFile(toqstr(outfile));
else if (os::is_terminal(os::STDOUT))
process->setStandardOutputFile(toqstr(os::stdoutdev()));
if (os::is_terminal(os::STDERR))
process->setStandardErrorFile(toqstr(os::stderrdev()));
@ -99,7 +135,7 @@ int Systemcall::startscript(Starttype how, string const & what)
// If the output has been redirected, we write it all at once.
// Even if we are not running in a terminal, the output could go
// to some log file, for example ~/.xsession-errors on *nix.
if (!os::is_terminal(os::STDOUT))
if (!os::is_terminal(os::STDOUT) && outfile.empty())
cout << fromqstr(QString::fromLocal8Bit(
process->readAllStandardOutput().data()));
if (!os::is_terminal(os::STDERR))
@ -108,8 +144,8 @@ int Systemcall::startscript(Starttype how, string const & what)
killProcess(process);
return exit_code;
#endif
}
#endif
} // namespace support
} // namespace lyx