Propagate sys.exit(code) up the call stack to the shell

SystemExitException is instantiated and thrown by Base::Interpreter
whenever the python interpreter executes a sys.exit(<exitCode>) call.
However, in the current implementation, the SystemExitException
effectively swallows the <exitCode> hence under this change,
SystemExitException has been extended to save the <exitCode> passed to
the sys.exit() call when it is instantiated and provides a new
getExitCode() accessor method to retrieve the <exitCode> in a
try/catch block.  MainGui.cpp was change to pass the corresponding
<exitCode> to the system exit() call so it is accessible in the shell.
This commit is contained in:
Bruce Lacey 2016-03-19 10:12:15 -07:00 committed by wmayer
parent 5393196c0e
commit 9816e48b07
3 changed files with 40 additions and 3 deletions

View File

@ -92,13 +92,46 @@ void PyException::ReportException (void) const
SystemExitException::SystemExitException()
{
_sErrMsg = "System exit";
// Set exception message and code based upon the pthon sys.exit() code and/or message
// based upon the the following sys.exit() call semantics.
//
// Invocation | _exitCode | _sErrMsg
// ---------------- + --------- + --------
// sys.exit(int#) | int# | "System Exit"
// sys.exit(string) | 1 | string
// sys.exit() | 1 | "System Exit"
long int errCode = 1;
std::string errMsg = "System exit";
PyObject *type, *value, *traceback, *code;
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
code = PyObject_GetAttrString(value, "code");
if (code != NULL && value != Py_None) {
Py_DECREF(value);
value = code;
}
if (PyInt_Check(value)) {
errCode = PyInt_AsLong(value);
}
else {
const char *str = PyString_AsString(value);
if (str)
errMsg = errMsg + ": " + str;
}
_sErrMsg = errMsg;
_exitCode = errCode;
}
SystemExitException::SystemExitException(const SystemExitException &inst)
: Exception(inst)
{
}
// ---------------------------------------------------------

View File

@ -87,6 +87,10 @@ public:
SystemExitException(void);
SystemExitException(const SystemExitException &inst);
virtual ~SystemExitException() throw() {}
const long getExitCode(void) const { return _exitCode;}
protected:
long int _exitCode;
};
/** If the application starts we release immediately the global interpreter lock

View File

@ -236,8 +236,8 @@ int main( int argc, char ** argv )
else
App::Application::runApplication();
}
catch (const Base::SystemExitException&) {
exit(0);
catch (const Base::SystemExitException& e) {
exit(e.getExitCode());
}
catch (const Base::Exception& e) {
e.ReportException();