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 <config.h>
#include "support/debug.h" #include "support/debug.h"
#include "support/lstrings.h"
#include "support/qstring_helpers.h" #include "support/qstring_helpers.h"
#include "support/Systemcall.h" #include "support/Systemcall.h"
#include "support/os.h" #include "support/os.h"
@ -40,9 +41,9 @@ static void killProcess(QProcess * p)
// Reuse of instance // Reuse of instance
#ifndef USE_QPROCESS
int Systemcall::startscript(Starttype how, string const & what) int Systemcall::startscript(Starttype how, string const & what)
{ {
#ifndef USE_QPROCESS
string command = what; string command = what;
if (how == DontWait) { if (how == DontWait) {
@ -57,14 +58,49 @@ int Systemcall::startscript(Starttype how, string const & what)
} }
return ::system(command.c_str()); return ::system(command.c_str());
}
#else #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; QProcess * process = new QProcess;
// Qt won't start the process if we redirect stdout/stderr in // Qt won't start the process if we redirect stdout/stderr in
// this way and they are not connected to a terminal (maybe // this way and they are not connected to a terminal (maybe
// because we were launched from some desktop GUI). // 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())); process->setStandardOutputFile(toqstr(os::stdoutdev()));
if (os::is_terminal(os::STDERR)) if (os::is_terminal(os::STDERR))
process->setStandardErrorFile(toqstr(os::stderrdev())); 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. // 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 // Even if we are not running in a terminal, the output could go
// to some log file, for example ~/.xsession-errors on *nix. // 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( cout << fromqstr(QString::fromLocal8Bit(
process->readAllStandardOutput().data())); process->readAllStandardOutput().data()));
if (!os::is_terminal(os::STDERR)) if (!os::is_terminal(os::STDERR))
@ -108,8 +144,8 @@ int Systemcall::startscript(Starttype how, string const & what)
killProcess(process); killProcess(process);
return exit_code; return exit_code;
#endif
} }
#endif
} // namespace support } // namespace support
} // namespace lyx } // namespace lyx