mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Allow immediate output of spawned processes for all platforms.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29668 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
ee39b28f99
commit
8fe984090f
@ -12,7 +12,7 @@ BUILT_SOURCES = $(PCH_FILE)
|
|||||||
######################### Qt stuff #############################
|
######################### Qt stuff #############################
|
||||||
#
|
#
|
||||||
|
|
||||||
MOCHEADER = SignalSlotPrivate.h
|
MOCHEADER = SignalSlotPrivate.h Systemcall.h
|
||||||
|
|
||||||
MOCEDFILES = $(MOCHEADER:%.h=moc_%.cpp)
|
MOCEDFILES = $(MOCHEADER:%.h=moc_%.cpp)
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ namespace support {
|
|||||||
|
|
||||||
static void killProcess(QProcess * p)
|
static void killProcess(QProcess * p)
|
||||||
{
|
{
|
||||||
|
p->disconnect();
|
||||||
p->closeReadChannel(QProcess::StandardOutput);
|
p->closeReadChannel(QProcess::StandardOutput);
|
||||||
p->closeReadChannel(QProcess::StandardError);
|
p->closeReadChannel(QProcess::StandardError);
|
||||||
p->close();
|
p->close();
|
||||||
@ -83,7 +84,6 @@ string const parsecmd(string const & cmd, string & outfile)
|
|||||||
}
|
}
|
||||||
outfile.erase();
|
outfile.erase();
|
||||||
return cmd;
|
return cmd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace anon
|
} // namespace anon
|
||||||
@ -94,18 +94,15 @@ int Systemcall::startscript(Starttype how, string const & what)
|
|||||||
string outfile;
|
string outfile;
|
||||||
QString cmd = toqstr(parsecmd(what, outfile));
|
QString cmd = toqstr(parsecmd(what, outfile));
|
||||||
QProcess * process = new QProcess;
|
QProcess * process = new QProcess;
|
||||||
|
ConOut console(process);
|
||||||
// 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 (!outfile.empty()) {
|
if (!outfile.empty()) {
|
||||||
// Check whether we have to simply throw away the output.
|
// Check whether we have to simply throw away the output.
|
||||||
if (outfile != os::nulldev())
|
if (outfile != os::nulldev())
|
||||||
process->setStandardOutputFile(toqstr(outfile));
|
process->setStandardOutputFile(toqstr(outfile));
|
||||||
} else if (os::is_terminal(os::STDOUT))
|
} else if (os::is_terminal(os::STDOUT))
|
||||||
process->setStandardOutputFile(toqstr(os::stdoutdev()));
|
console.showout();
|
||||||
if (os::is_terminal(os::STDERR))
|
if (os::is_terminal(os::STDERR))
|
||||||
process->setStandardErrorFile(toqstr(os::stderrdev()));
|
console.showerr();
|
||||||
|
|
||||||
process->start(cmd);
|
process->start(cmd);
|
||||||
if (!process->waitForStarted(3000)) {
|
if (!process->waitForStarted(3000)) {
|
||||||
@ -115,8 +112,10 @@ int Systemcall::startscript(Starttype how, string const & what)
|
|||||||
LYXERR0("status " << process->exitStatus());
|
LYXERR0("status " << process->exitStatus());
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
if (how == DontWait)
|
if (how == DontWait) {
|
||||||
|
// TODO delete process later
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!process->waitForFinished(180000)) {
|
if (!process->waitForFinished(180000)) {
|
||||||
LYXERR0("Qprocess " << cmd << " did not finished!");
|
LYXERR0("Qprocess " << cmd << " did not finished!");
|
||||||
@ -147,6 +146,57 @@ int Systemcall::startscript(Starttype how, string const & what)
|
|||||||
killProcess(process);
|
killProcess(process);
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConOut::ConOut(QProcess * proc) : proc_(proc), outindex_(0), errindex_(0),
|
||||||
|
showout_(false), showerr_(false)
|
||||||
|
{
|
||||||
|
connect(proc, SIGNAL(readyReadStandardOutput()), SLOT(stdOut()));
|
||||||
|
connect(proc, SIGNAL(readyReadStandardError()), SLOT(stdErr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConOut::~ConOut()
|
||||||
|
{
|
||||||
|
cout.flush();
|
||||||
|
cerr.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConOut::stdOut()
|
||||||
|
{
|
||||||
|
if (showout_) {
|
||||||
|
char c;
|
||||||
|
proc_->setReadChannel(QProcess::StandardOutput);
|
||||||
|
while (proc_->getChar(&c)) {
|
||||||
|
outdata_[outindex_++] = c;
|
||||||
|
if (c == '\n' || outindex_ + 1 == bufsize_) {
|
||||||
|
outdata_[outindex_] = '\0';
|
||||||
|
outindex_ = 0;
|
||||||
|
cout << outdata_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConOut::stdErr()
|
||||||
|
{
|
||||||
|
if (showerr_) {
|
||||||
|
char c;
|
||||||
|
proc_->setReadChannel(QProcess::StandardError);
|
||||||
|
while (proc_->getChar(&c)) {
|
||||||
|
errdata_[errindex_++] = c;
|
||||||
|
if (c == '\n' || errindex_ + 1 == bufsize_) {
|
||||||
|
errdata_[errindex_] = '\0';
|
||||||
|
errindex_ = 0;
|
||||||
|
cerr << errdata_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_Systemcall.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace support
|
} // namespace support
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
#define SYSTEMCALL_H
|
#define SYSTEMCALL_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QProcess;
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
namespace support {
|
namespace support {
|
||||||
@ -45,6 +48,48 @@ public:
|
|||||||
int startscript(Starttype how, std::string const & what);
|
int startscript(Starttype how, std::string const & what);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs to the console terminal the line buffered standard output and
|
||||||
|
* error of a spawned process when there is a controlling terminal and
|
||||||
|
* stdout/stderr have not been redirected.
|
||||||
|
*/
|
||||||
|
class ConOut : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConOut(QProcess * proc);
|
||||||
|
~ConOut();
|
||||||
|
|
||||||
|
/// Should the standard output be displayed?
|
||||||
|
void showout() { showout_ = true; }
|
||||||
|
|
||||||
|
/// Should the standard error be displayed?
|
||||||
|
void showerr() { showerr_ = true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the process to monitor.
|
||||||
|
QProcess * proc_;
|
||||||
|
/// Index to the standard output buffer.
|
||||||
|
size_t outindex_;
|
||||||
|
/// Index to the standard error buffer.
|
||||||
|
size_t errindex_;
|
||||||
|
/// Size of buffers.
|
||||||
|
static size_t const bufsize_ = 200;
|
||||||
|
/// Standard output buffer.
|
||||||
|
char outdata_[bufsize_];
|
||||||
|
/// Standard error buffer.
|
||||||
|
char errdata_[bufsize_];
|
||||||
|
///
|
||||||
|
bool showout_;
|
||||||
|
///
|
||||||
|
bool showerr_;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void stdOut();
|
||||||
|
void stdErr();
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace support
|
} // namespace support
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
|
||||||
|
@ -39,12 +39,6 @@ void init(int argc, char * argv[]);
|
|||||||
/// Returns the name of the NULL device (/dev/null, null).
|
/// Returns the name of the NULL device (/dev/null, null).
|
||||||
std::string const & nulldev();
|
std::string const & nulldev();
|
||||||
|
|
||||||
/// Returns the name of the stdout device (/dev/stdout, /dev/tty, conout$).
|
|
||||||
std::string const & stdoutdev();
|
|
||||||
|
|
||||||
/// Returns the name of the stderr device (/dev/stderr, /dev/tty, conout$).
|
|
||||||
std::string const & stderrdev();
|
|
||||||
|
|
||||||
/// Tells whether \p channel is connected to a terminal or not.
|
/// Tells whether \p channel is connected to a terminal or not.
|
||||||
bool is_terminal(io_channel channel);
|
bool is_terminal(io_channel channel);
|
||||||
|
|
||||||
|
@ -240,20 +240,6 @@ string const & nulldev()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string const & stdoutdev()
|
|
||||||
{
|
|
||||||
static string const stdoutdev_ = "/dev/stdout";
|
|
||||||
return stdoutdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string const & stderrdev()
|
|
||||||
{
|
|
||||||
static string const stderrdev_ = "/dev/stderr";
|
|
||||||
return stderrdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool is_terminal(io_channel channel)
|
bool is_terminal(io_channel channel)
|
||||||
{
|
{
|
||||||
return isatty(channel);
|
return isatty(channel);
|
||||||
|
@ -30,23 +30,8 @@ namespace lyx {
|
|||||||
namespace support {
|
namespace support {
|
||||||
namespace os {
|
namespace os {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
string stdoutdev_ = "/dev/stdout";
|
|
||||||
string stderrdev_ = "/dev/stderr";
|
|
||||||
|
|
||||||
} // namespace anon
|
|
||||||
|
|
||||||
void init(int, char *[])
|
void init(int, char *[])
|
||||||
{
|
{}
|
||||||
// Check whether /dev/stdout and /dev/stderr are available,
|
|
||||||
// otherwise default to /dev/tty.
|
|
||||||
if (access(stdoutdev_.c_str(), W_OK) != 0
|
|
||||||
|| access(stderrdev_.c_str(), W_OK) != 0) {
|
|
||||||
stdoutdev_ = "/dev/tty";
|
|
||||||
stderrdev_ = "/dev/tty";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string current_root()
|
string current_root()
|
||||||
@ -145,18 +130,6 @@ string const & nulldev()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string const & stdoutdev()
|
|
||||||
{
|
|
||||||
return stdoutdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string const & stderrdev()
|
|
||||||
{
|
|
||||||
return stderrdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool is_terminal(io_channel channel)
|
bool is_terminal(io_channel channel)
|
||||||
{
|
{
|
||||||
return isatty(channel);
|
return isatty(channel);
|
||||||
|
@ -296,28 +296,23 @@ string const & nulldev()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string const & stdoutdev()
|
|
||||||
{
|
|
||||||
static string const stdoutdev_ = "conout$";
|
|
||||||
return stdoutdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string const & stderrdev()
|
|
||||||
{
|
|
||||||
static string const stderrdev_ = "conout$";
|
|
||||||
return stderrdev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool is_terminal(io_channel channel)
|
bool is_terminal(io_channel channel)
|
||||||
{
|
{
|
||||||
// FIXME: Passing conout$ to Qt fails, most probably for the
|
switch (channel) {
|
||||||
// reason explained here:
|
case STDIN:
|
||||||
// http://support.microsoft.com/?scid=kb%3Ben-us%3B90088&x=15&y=15
|
if (GetStdHandle(STD_INPUT_HANDLE) == NULL)
|
||||||
// How to convince Qt to open conout$ in FILE_SHARE_WRITE mode?
|
return false;
|
||||||
// For the time being, we assume we are not running in a terminal.
|
break;
|
||||||
return false;
|
case STDOUT:
|
||||||
|
if (GetStdHandle(STD_OUTPUT_HANDLE) == NULL)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case STDERR:
|
||||||
|
if (GetStdHandle(STD_ERROR_HANDLE) == NULL)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user