Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
ProgramLauncher.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "ProgramLauncher.h"
8 
9 #include <iostream>
10 #include <sstream>
11 #include <sys/wait.h>
12 
13 #include <QLocalServer>
14 #include <QLocalSocket>
15 #include <QProcess>
16 
17 #include "Application.h"
18 #include "FileName.h"
19 #include "IException.h"
20 #include "IString.h"
21 
22 using namespace std;
23 
24 namespace Isis {
37  void ProgramLauncher::RunIsisProgram(QString programName,
38  QString parameters) {
39  FileName program(programName);
40  FileName isisExecutableFileName("$ISISROOT/bin/" + program.name());
41  bool isIsisProgram = false;
42 
43  if(isisExecutableFileName.fileExists()) {
44  isIsisProgram = true;
45  program = isisExecutableFileName;
46  }
47 
48  QString command = program.expanded() + " " + parameters +
49  " -pid=" + toString(getpid());
50 
51  if(!isIsisProgram) {
52  QString msg = "Program [" + programName + "] does not appear to be a "
53  "valid Isis program";
54  throw IException(IException::Unknown, msg, _FILEINFO_);
55  }
56 
57  QString serverName = "isis_" + Application::UserName() +
58  "_" + toString(getpid());
59 
60  QLocalServer server;
61  server.listen(serverName);
62 
63  QProcess childProcess;
64  childProcess.setProcessChannelMode(QProcess::ForwardedChannels);
65  childProcess.start(command);
66  childProcess.waitForStarted();
67 
68  bool connected = false;
69 
70  while(!connected && childProcess.state() != QProcess::NotRunning) {
71  // Give time for the process to connect to us or for it to finish
72  // wait 30s for the new connection....
73  connected = server.waitForNewConnection(30000);
74  childProcess.waitForFinished(100);
75  }
76 
77  if(!connected) {
78  QString msg = "Isis child process failed to communicate with parent";
79  throw IException(IException::Programmer, msg, _FILEINFO_);
80  }
81 
82  QLocalSocket *childSocket = server.nextPendingConnection();
83  IException errors;
84 
85  // Don't return until we're done running this program
86  while(childSocket->state() != QLocalSocket::UnconnectedState) {
87  bool insideCode = true;
88  bool messageDone = false;
89 
90  QString code;
91  QString message;
92  QByteArray lineData;
93 
94  if(childSocket->waitForReadyRead(1000)) {
95  lineData = childSocket->read(childSocket->bytesAvailable());
96 
97  for(int i = 0; i < lineData.size(); i++) {
98  if(insideCode) {
99  if(lineData[i] != (char)27) {
100  code += lineData[i];
101  }
102  else {
103  insideCode = false;
104  }
105  }
106  else {
107  if(lineData[i] != (char)27) {
108  message += lineData[i];
109  }
110  else {
111  messageDone = true;
112  insideCode = true;
113  i ++; // skip \n that should always exist here
114  }
115  }
116 
117  if(messageDone) {
118  errors.append(
119  ProcessIsisMessageFromChild(code, message));
120  code = "";
121  message = "";
122  messageDone = false;
123  }
124  }
125  }
126  }
127 
128  childProcess.waitForFinished();
129 
130  if(childProcess.exitCode() != 0) {
131  QString msg = "Running Isis program [" + programName + "] failed with "
132  "return status [" + toString(childProcess.exitCode()) + "]";
133  throw IException(errors, IException::Unknown, msg, _FILEINFO_);
134  }
135  }
136 
137 
148  IException
149  ProgramLauncher::ProcessIsisMessageFromChild(QString code, QString msg) {
150  IException errors;
151 
152  if(code == "PROGRESSTEXT" && iApp) {
153  iApp->UpdateProgress(msg, true);
154  }
155  else if(code == "PROGRESS" && iApp) {
156  iApp->UpdateProgress(toInt(msg), true);
157  }
158  else if(code == "LOG" && iApp) {
159  stringstream msgStream;
160  msgStream << msg;
161  Pvl logPvl;
162  msgStream >> logPvl;
163 
164  if(logPvl.groups() == 1 &&
165  logPvl.keywords() == 0 &&
166  logPvl.objects() == 0) {
167  iApp->Log(logPvl.group(0));
168  }
169  }
170  else if(code == "GUILOG" && iApp) {
171  iApp->GuiLog(msg);
172  }
173  else if(code == "ERROR") {
174  stringstream msgStream;
175  msgStream << msg;
176  Pvl errorPvl;
177  msgStream >> errorPvl;
178 
179  for(int i = 0; i < errorPvl.groups(); i++) {
180  PvlGroup &g = errorPvl.group(i);
181  QString eclass = g["Class"];
182  QString emsg = g["Message"];
183  int ecode = g["Code"];
184  QString efile = g["File"];
185  int eline = g["Line"];
186 
187  errors.append(
188  IException((IException::ErrorType)ecode, emsg, efile.toLatin1().data(), eline));
189  }
190  }
191 
192  return errors;
193  }
194 
195 
207  void ProgramLauncher::RunSystemCommand(QString fullCommand) {
208  int status = system(fullCommand.toLatin1().data());
209 
210  if(status != 0) {
211  QString msg = "Executing command [" + fullCommand +
212  "] failed with return status [" + toString(status) + "]";
213  throw IException(IException::Programmer, msg, _FILEINFO_);
214  }
215  }
216 } //end namespace isis
Isis::Application::GuiLog
static void GuiLog(const Pvl &results)
Writes the Pvl results to the sessionlog, but not to the printfile.
Definition: Application.cpp:395
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::IException::append
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception's causational exc...
Definition: IException.cpp:409
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::toInt
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:93
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Application::UpdateProgress
void UpdateProgress(const QString &text, bool print)
Updates the progress bar in the gui.
Definition: Application.cpp:740
std
Namespace for the standard library.
Isis::Application::Log
static void Log(PvlGroup &results)
Writes Pvl results to sessionlog and printfile.
Definition: Application.cpp:353
Isis::IException::ErrorType
ErrorType
Contains a set of exception error types.
Definition: IException.h:111
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:17:05