mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-02-03 09:44:24 -05:00
Improved subprocess handling and error reporting
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6675 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
a45ea3cdff
commit
cc8d2130c6
147
mainwindow.cpp
147
mainwindow.cpp
@ -143,6 +143,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
unsigned downSampleFactor, QNetworkAccessManager * network_manager,
|
unsigned downSampleFactor, QNetworkAccessManager * network_manager,
|
||||||
QWidget *parent) :
|
QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
|
m_valid {true},
|
||||||
m_dataDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)},
|
m_dataDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)},
|
||||||
m_revision {revision ()},
|
m_revision {revision ()},
|
||||||
m_multiple {multiple},
|
m_multiple {multiple},
|
||||||
@ -382,17 +383,34 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
setWindowTitle (program_title ());
|
setWindowTitle (program_title ());
|
||||||
createStatusBar();
|
createStatusBar();
|
||||||
|
|
||||||
connect(&proc_jt9, SIGNAL(readyReadStandardOutput()),this, SLOT(readFromStdout()));
|
connect(&proc_jt9, &QProcess::readyReadStandardOutput, this, &MainWindow::readFromStdout);
|
||||||
connect(&proc_jt9, SIGNAL(error(QProcess::ProcessError)),this, SLOT(jt9_error(QProcess::ProcessError)));
|
connect(&proc_jt9, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error),
|
||||||
connect(&proc_jt9, SIGNAL(readyReadStandardError()),this, SLOT(readFromStderr()));
|
[this] (QProcess::ProcessError error) {
|
||||||
|
subProcessError (&proc_jt9, error);
|
||||||
|
});
|
||||||
|
connect(&proc_jt9, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished),
|
||||||
|
[this] (int exitCode, QProcess::ExitStatus status) {
|
||||||
|
subProcessFailed (&proc_jt9, exitCode, status);
|
||||||
|
});
|
||||||
|
|
||||||
connect(&p1, SIGNAL(readyReadStandardOutput()),this, SLOT(p1ReadFromStdout()));
|
connect(&p1, &QProcess::readyReadStandardOutput, this, &MainWindow::p1ReadFromStdout);
|
||||||
connect(&p1, SIGNAL(error(QProcess::ProcessError)),this, SLOT(p1Error(QProcess::ProcessError)));
|
connect(&proc_jt9, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error),
|
||||||
connect(&p1, SIGNAL(readyReadStandardError()),this, SLOT(p1ReadFromStderr()));
|
[this] (QProcess::ProcessError error) {
|
||||||
|
subProcessError (&p1, error);
|
||||||
|
});
|
||||||
|
connect(&p1, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished),
|
||||||
|
[this] (int exitCode, QProcess::ExitStatus status) {
|
||||||
|
subProcessFailed (&p1, exitCode, status);
|
||||||
|
});
|
||||||
|
|
||||||
// connect(&p3, SIGNAL(readyReadStandardOutput()),this, SLOT(p3ReadFromStdout()));
|
connect(&p3, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error),
|
||||||
connect(&p3, SIGNAL(error(QProcess::ProcessError)),this, SLOT(p3Error(QProcess::ProcessError)));
|
[this] (QProcess::ProcessError error) {
|
||||||
connect(&p3, SIGNAL(readyReadStandardError()),this, SLOT(p3ReadFromStderr()));
|
subProcessError (&p3, error);
|
||||||
|
});
|
||||||
|
connect(&p3, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished),
|
||||||
|
[this] (int exitCode, QProcess::ExitStatus status) {
|
||||||
|
subProcessFailed (&p3, exitCode, status);
|
||||||
|
});
|
||||||
|
|
||||||
// Hook up working frequencies.
|
// Hook up working frequencies.
|
||||||
ui->bandComboBox->setModel (m_config.frequencies ());
|
ui->bandComboBox->setModel (m_config.frequencies ());
|
||||||
@ -485,7 +503,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
m_txFirst=false;
|
m_txFirst=false;
|
||||||
m_btxok=false;
|
m_btxok=false;
|
||||||
m_restart=false;
|
m_restart=false;
|
||||||
m_killAll=false;
|
|
||||||
m_widebandDecode=false;
|
m_widebandDecode=false;
|
||||||
m_ntx=1;
|
m_ntx=1;
|
||||||
|
|
||||||
@ -706,6 +723,9 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
int ntr[]={5,10,15,30};
|
int ntr[]={5,10,15,30};
|
||||||
m_TRperiod=ntr[m_TRindex-11];
|
m_TRperiod=ntr[m_TRindex-11];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this must be the last statement of constructor
|
||||||
|
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------- MainWindow destructor
|
//--------------------------------------------------- MainWindow destructor
|
||||||
@ -1464,6 +1484,43 @@ void MainWindow::createStatusBar() //createStatusBar
|
|||||||
progressBar->setFormat("%v/%m");
|
progressBar->setFormat("%v/%m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::subProcessFailed (QProcess * process, int exit_code, QProcess::ExitStatus status)
|
||||||
|
{
|
||||||
|
if (m_valid && (exit_code || QProcess::NormalExit != status))
|
||||||
|
{
|
||||||
|
QStringList arguments;
|
||||||
|
for (auto argument: process->arguments ())
|
||||||
|
{
|
||||||
|
if (argument.contains (' ')) argument = '"' + argument + '"';
|
||||||
|
arguments << argument;
|
||||||
|
}
|
||||||
|
msgBox (tr ("Subprocess failed with exit code %1\nRunning:%2\n%3")
|
||||||
|
.arg (exit_code)
|
||||||
|
.arg (process->program () + ' ' + arguments.join (' '))
|
||||||
|
.arg (QString {process->readAllStandardError()}));
|
||||||
|
close ();
|
||||||
|
m_valid = false; // ensures exit if still constructing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::subProcessError (QProcess * process, QProcess::ProcessError)
|
||||||
|
{
|
||||||
|
if (m_valid)
|
||||||
|
{
|
||||||
|
QStringList arguments;
|
||||||
|
for (auto argument: process->arguments ())
|
||||||
|
{
|
||||||
|
if (argument.contains (' ')) argument = '"' + argument + '"';
|
||||||
|
arguments << argument;
|
||||||
|
}
|
||||||
|
msgBox (tr ("Subprocess error\nRunning: %1\n%2")
|
||||||
|
.arg (process->program () + ' ' + arguments.join (' '))
|
||||||
|
.arg (process->errorString ()));
|
||||||
|
close ();
|
||||||
|
m_valid = false; // ensures exit if still constructing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent * e)
|
void MainWindow::closeEvent(QCloseEvent * e)
|
||||||
{
|
{
|
||||||
m_config.transceiver_offline ();
|
m_config.transceiver_offline ();
|
||||||
@ -1474,7 +1531,6 @@ void MainWindow::closeEvent(QCloseEvent * e)
|
|||||||
m_mouseCmnds.reset ();
|
m_mouseCmnds.reset ();
|
||||||
|
|
||||||
killFile ();
|
killFile ();
|
||||||
m_killAll=true;
|
|
||||||
mem_jt9->detach();
|
mem_jt9->detach();
|
||||||
QFile quitFile {m_config.temp_dir ().absoluteFilePath (".quit")};
|
QFile quitFile {m_config.temp_dir ().absoluteFilePath (".quit")};
|
||||||
quitFile.open(QIODevice::ReadWrite);
|
quitFile.open(QIODevice::ReadWrite);
|
||||||
@ -1992,19 +2048,16 @@ void::MainWindow::fast_decode_done()
|
|||||||
ui->DecodeButton->setChecked (false);
|
ui->DecodeButton->setChecked (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::jt9_error (QProcess::ProcessError e)
|
void MainWindow::decodeDone ()
|
||||||
{
|
{
|
||||||
if(!m_killAll) {
|
dec_data.params.nagain=0;
|
||||||
msgBox("Error starting or running\n" + m_appDir + "/jt9 -s");
|
dec_data.params.ndiskdat=0;
|
||||||
qDebug() << e; // silence compiler warning
|
m_nclearave=0;
|
||||||
exit(1);
|
QFile {m_config.temp_dir ().absoluteFilePath (".lock")}.open(QIODevice::ReadWrite);
|
||||||
}
|
ui->DecodeButton->setChecked (false);
|
||||||
}
|
decodeBusy(false);
|
||||||
|
m_RxLog=0;
|
||||||
void MainWindow::readFromStderr() //readFromStderr
|
m_blankLine=true;
|
||||||
{
|
|
||||||
QByteArray t=proc_jt9.readAllStandardError();
|
|
||||||
msgBox(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::readFromStdout() //readFromStdout
|
void MainWindow::readFromStdout() //readFromStdout
|
||||||
@ -2033,15 +2086,8 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
if(t.indexOf("<DecodeFinished>") >= 0) {
|
if(t.indexOf("<DecodeFinished>") >= 0) {
|
||||||
m_bDecoded = (t.mid(23,1).toInt()==1);
|
m_bDecoded = (t.mid(23,1).toInt()==1);
|
||||||
if(!m_diskData) killFileTimer->start (3*1000*m_TRperiod/4); //Kill in 45 s
|
if(!m_diskData) killFileTimer->start (3*1000*m_TRperiod/4); //Kill in 45 s
|
||||||
dec_data.params.nagain=0;
|
decodeDone ();
|
||||||
dec_data.params.ndiskdat=0;
|
|
||||||
m_nclearave=0;
|
|
||||||
QFile {m_config.temp_dir ().absoluteFilePath (".lock")}.open(QIODevice::ReadWrite);
|
|
||||||
ui->DecodeButton->setChecked (false);
|
|
||||||
decodeBusy(false);
|
|
||||||
m_RxLog=0;
|
|
||||||
m_startAnother=m_loopall;
|
m_startAnother=m_loopall;
|
||||||
m_blankLine=true;
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
QFile f {m_dataDir.absoluteFilePath ("ALL.TXT")};
|
QFile f {m_dataDir.absoluteFilePath ("ALL.TXT")};
|
||||||
@ -5003,21 +5049,6 @@ void MainWindow::on_syncSpinBox_valueChanged(int n)
|
|||||||
m_minSync=n;
|
m_minSync=n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::p1ReadFromStderr() //p1readFromStderr
|
|
||||||
{
|
|
||||||
QByteArray t=p1.readAllStandardError();
|
|
||||||
msgBox(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::p1Error (QProcess::ProcessError e)
|
|
||||||
{
|
|
||||||
if(!m_killAll) {
|
|
||||||
msgBox("Error starting or running\n" + m_appDir + "/wsprd");
|
|
||||||
qDebug() << e; // silence compiler warning
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
||||||
{
|
{
|
||||||
QString t1;
|
QString t1;
|
||||||
@ -5180,30 +5211,6 @@ void MainWindow::uploadResponse(QString response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::p3ReadFromStdout() //p3readFromStdout
|
|
||||||
{
|
|
||||||
QByteArray t=p3.readAllStandardOutput();
|
|
||||||
if(t.length()>0) {
|
|
||||||
msgBox("user_hardware stdout:\n\n"+t+"\n"+m_cmnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::p3ReadFromStderr() //p3readFromStderr
|
|
||||||
{
|
|
||||||
QByteArray t=p3.readAllStandardError();
|
|
||||||
if(t.length()>0) {
|
|
||||||
msgBox("user_hardware stderr:\n\n"+t+"\n"+m_cmnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::p3Error(QProcess::ProcessError e) //p3rror
|
|
||||||
{
|
|
||||||
msgBox("Error attempting to run user_hardware.\n\n"+m_cmnd);
|
|
||||||
qDebug() << e; // silence compiler warning
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_TxPowerComboBox_currentIndexChanged(const QString &arg1)
|
void MainWindow::on_TxPowerComboBox_currentIndexChanged(const QString &arg1)
|
||||||
{
|
{
|
||||||
int i1=arg1.indexOf(" ");
|
int i1=arg1.indexOf(" ");
|
||||||
|
12
mainwindow.h
12
mainwindow.h
@ -100,11 +100,7 @@ public slots:
|
|||||||
void doubleClickOnCall(bool shift, bool ctrl);
|
void doubleClickOnCall(bool shift, bool ctrl);
|
||||||
void doubleClickOnCall2(bool shift, bool ctrl);
|
void doubleClickOnCall2(bool shift, bool ctrl);
|
||||||
void readFromStdout();
|
void readFromStdout();
|
||||||
void readFromStderr();
|
|
||||||
void jt9_error(QProcess::ProcessError);
|
|
||||||
void p1ReadFromStdout();
|
void p1ReadFromStdout();
|
||||||
void p1ReadFromStderr();
|
|
||||||
void p1Error(QProcess::ProcessError);
|
|
||||||
void setXIT(int n, Frequency base = 0u);
|
void setXIT(int n, Frequency base = 0u);
|
||||||
void setFreq4(int rxFreq, int txFreq);
|
void setFreq4(int rxFreq, int txFreq);
|
||||||
void msgAvgDecode2();
|
void msgAvgDecode2();
|
||||||
@ -233,9 +229,6 @@ private slots:
|
|||||||
void TxAgain();
|
void TxAgain();
|
||||||
void RxQSY();
|
void RxQSY();
|
||||||
void uploadResponse(QString response);
|
void uploadResponse(QString response);
|
||||||
void p3ReadFromStdout();
|
|
||||||
void p3ReadFromStderr();
|
|
||||||
void p3Error(QProcess::ProcessError e);
|
|
||||||
void on_WSPRfreqSpinBox_valueChanged(int n);
|
void on_WSPRfreqSpinBox_valueChanged(int n);
|
||||||
void on_pbTxNext_clicked(bool b);
|
void on_pbTxNext_clicked(bool b);
|
||||||
void on_actionEcho_Graph_triggered();
|
void on_actionEcho_Graph_triggered();
|
||||||
@ -277,6 +270,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
void astroUpdate ();
|
void astroUpdate ();
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
QDir m_dataDir;
|
QDir m_dataDir;
|
||||||
QString m_revision;
|
QString m_revision;
|
||||||
bool m_multiple;
|
bool m_multiple;
|
||||||
@ -382,7 +376,6 @@ private:
|
|||||||
bool m_widebandDecode;
|
bool m_widebandDecode;
|
||||||
bool m_call3Modified;
|
bool m_call3Modified;
|
||||||
bool m_dataAvailable;
|
bool m_dataAvailable;
|
||||||
bool m_killAll;
|
|
||||||
bool m_bDecoded;
|
bool m_bDecoded;
|
||||||
bool m_monitorStartOFF;
|
bool m_monitorStartOFF;
|
||||||
bool m_pskReporterInit;
|
bool m_pskReporterInit;
|
||||||
@ -576,6 +569,9 @@ private:
|
|||||||
void CQRxFreq();
|
void CQRxFreq();
|
||||||
void save_wave_file (QString const& name, short const * data, int seconds) const;
|
void save_wave_file (QString const& name, short const * data, int seconds) const;
|
||||||
void read_wav_file (QString const& fname);
|
void read_wav_file (QString const& fname);
|
||||||
|
void decodeDone ();
|
||||||
|
void subProcessFailed (QProcess *, int exit_code, QProcess::ExitStatus);
|
||||||
|
void subProcessError (QProcess *, QProcess::ProcessError);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int killbyname(const char* progName);
|
extern int killbyname(const char* progName);
|
||||||
|
Loading…
Reference in New Issue
Block a user