Pass exit status of panda process on to panda3d process (non-Windows only so far)
This commit is contained in:
parent
82f7813927
commit
4342ff741b
|
|
@ -634,13 +634,13 @@ class AppRunner(DirectObject):
|
|||
try:
|
||||
taskMgr.run()
|
||||
|
||||
except SystemExit:
|
||||
except SystemExit as err:
|
||||
# Presumably the window has already been shut down here, but shut
|
||||
# it down again for good measure.
|
||||
if hasattr(__builtin__, "base"):
|
||||
base.destroy()
|
||||
|
||||
self.notify.info("Normal exit.")
|
||||
self.notify.info("Normal exit with status %d." % err.code)
|
||||
raise
|
||||
|
||||
except:
|
||||
|
|
|
|||
|
|
@ -150,10 +150,10 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!run_p3dpython(program_name, archive_file, input_handle, output_handle,
|
||||
NULL, interactive_console)) {
|
||||
int status = run_p3dpython(program_name, archive_file, input_handle,
|
||||
output_handle, NULL, interactive_console);
|
||||
if (status != 0) {
|
||||
cerr << "Failure on startup.\n";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,8 +137,10 @@ P3DPythonRun::
|
|||
// Access: Public
|
||||
// Description: Runs the embedded Python process. This method does
|
||||
// not return until the plugin is ready to exit.
|
||||
//
|
||||
// Returns the exit status, which will be 0 on success.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DPythonRun::
|
||||
int P3DPythonRun::
|
||||
run_python() {
|
||||
#if defined(_WIN32) && defined(USE_DEBUG_PYTHON)
|
||||
// On Windows, in a debug build, we have to preload sys.dll_suffix =
|
||||
|
|
@ -156,7 +158,7 @@ run_python() {
|
|||
if (panda3d_module == NULL) {
|
||||
nout << "Failed to create panda3d module:\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set the __path__ such that it can find panda3d/core.pyd, etc.
|
||||
|
|
@ -174,7 +176,7 @@ run_python() {
|
|||
if (vfsimporter == NULL) {
|
||||
nout << "Failed to import _vfsimporter:\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
Py_DECREF(vfsimporter);
|
||||
|
||||
|
|
@ -183,7 +185,7 @@ run_python() {
|
|||
if (vfsimporter_module == NULL) {
|
||||
nout << "Failed to import VFSImporter:\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// And register the VFSImporter.
|
||||
|
|
@ -191,7 +193,7 @@ run_python() {
|
|||
if (result == NULL) {
|
||||
nout << "Failed to call VFSImporter.register():\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
Py_DECREF(vfsimporter_module);
|
||||
|
|
@ -203,12 +205,12 @@ run_python() {
|
|||
PT(Multifile) mf = new Multifile;
|
||||
if (!mf->open_read(_archive_file)) {
|
||||
nout << "Could not read " << _archive_file << "\n";
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
if (!vfs->mount(mf, dir, VirtualFileSystem::MF_read_only)) {
|
||||
nout << "Could not mount " << _archive_file << "\n";
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// And finally, we can import the startup module.
|
||||
|
|
@ -216,7 +218,7 @@ run_python() {
|
|||
if (app_runner_module == NULL) {
|
||||
nout << "Failed to import direct.p3d.AppRunner\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pointers to the objects needed within the module.
|
||||
|
|
@ -224,7 +226,7 @@ run_python() {
|
|||
if (app_runner_class == NULL) {
|
||||
nout << "Failed to get AppRunner class\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Construct an instance of AppRunner.
|
||||
|
|
@ -232,7 +234,7 @@ run_python() {
|
|||
if (_runner == NULL) {
|
||||
nout << "Failed to construct AppRunner instance\n";
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
Py_DECREF(app_runner_class);
|
||||
|
||||
|
|
@ -240,35 +242,35 @@ run_python() {
|
|||
_undefined_object_class = PyObject_GetAttrString(app_runner_module, "UndefinedObject");
|
||||
if (_undefined_object_class == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// And the "Undefined" instance.
|
||||
_undefined = PyObject_GetAttrString(app_runner_module, "Undefined");
|
||||
if (_undefined == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the ConcreteStruct class.
|
||||
_concrete_struct_class = PyObject_GetAttrString(app_runner_module, "ConcreteStruct");
|
||||
if (_concrete_struct_class == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the BrowserObject class.
|
||||
_browser_object_class = PyObject_GetAttrString(app_runner_module, "BrowserObject");
|
||||
if (_browser_object_class == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the global TaskManager.
|
||||
_taskMgr = PyObject_GetAttrString(app_runner_module, "taskMgr");
|
||||
if (_taskMgr == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Py_DECREF(app_runner_module);
|
||||
|
|
@ -285,12 +287,12 @@ run_python() {
|
|||
PyObject *p3dpython = Py_InitModule("p3dpython", p3dpython_methods);
|
||||
if (p3dpython == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
PyObject *request_func = PyObject_GetAttrString(p3dpython, "request_func");
|
||||
if (request_func == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Now pass that func pointer back to our AppRunner instance, so it
|
||||
|
|
@ -298,7 +300,7 @@ run_python() {
|
|||
result = PyObject_CallMethod(_runner, (char *)"setRequestFunc", (char *)"N", request_func);
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
|
||||
|
|
@ -318,7 +320,7 @@ run_python() {
|
|||
PyObject *check_comm = PyObject_GetAttrString(p3dpython, "check_comm");
|
||||
if (check_comm == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Add it to the task manager. We do this instead of constructing a
|
||||
|
|
@ -326,7 +328,7 @@ run_python() {
|
|||
result = PyObject_CallMethod(_taskMgr, (char *)"add", (char *)"Ns", check_comm, "check_comm");
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
|
||||
|
|
@ -334,18 +336,30 @@ run_python() {
|
|||
// taskMgr.run()).
|
||||
PyObject *done = PyObject_CallMethod(_runner, (char *)"run", (char *)"");
|
||||
if (done == NULL) {
|
||||
int status = 1;
|
||||
|
||||
// An uncaught application exception, and not handled by
|
||||
// appRunner.exceptionHandler.
|
||||
PyErr_Print();
|
||||
// appRunner.exceptionHandler. If it is a SystemExit, extract
|
||||
// the exit status that we should return.
|
||||
if (PyErr_Occurred() == PyExc_SystemExit) {
|
||||
PyObject *ptype, *ptraceback;
|
||||
PySystemExitObject *value = NULL;
|
||||
PyErr_Fetch(&ptype, (PyObject **)&value, &ptraceback);
|
||||
if (value != NULL) {
|
||||
status = (int)PyInt_AsLong(value->code);
|
||||
}
|
||||
} else {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
if (_interactive_console) {
|
||||
// Give an interactive user a chance to explore the exception.
|
||||
run_interactive_console();
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We're done.
|
||||
return false;
|
||||
return status;
|
||||
}
|
||||
|
||||
// A normal exit from the taskManager. We're presumably done.
|
||||
|
|
@ -355,7 +369,7 @@ run_python() {
|
|||
run_interactive_console();
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public:
|
|||
const char *log_pathname, bool interactive_console);
|
||||
~P3DPythonRun();
|
||||
|
||||
bool run_python();
|
||||
int run_python();
|
||||
|
||||
void set_window_open(P3DCInstance *inst, bool is_open);
|
||||
void request_keyboard_focus(P3DCInstance *inst);
|
||||
|
|
|
|||
|
|
@ -179,18 +179,27 @@ shutdown() {
|
|||
result = waitpid(_p3dpython_pid, &status, WNOHANG);
|
||||
}
|
||||
_p3dpython_pid = -1;
|
||||
|
||||
|
||||
nout << "Python process has successfully stopped.\n";
|
||||
if (WIFEXITED(status)) {
|
||||
nout << " exited normally, status = "
|
||||
<< WEXITSTATUS(status) << "\n";
|
||||
int code = WEXITSTATUS(status);
|
||||
|
||||
nout << " exited normally, status = " << code << "\n";
|
||||
if (code != 0) {
|
||||
_exit(code);
|
||||
}
|
||||
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
nout << " signalled by " << WTERMSIG(status) << ", core = "
|
||||
nout << " signalled by " << WTERMSIG(status) << ", core = "
|
||||
<< WCOREDUMP(status) << "\n";
|
||||
|
||||
// This seems to be a popular shell convention.
|
||||
_exit(128 + WTERMSIG(status));
|
||||
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
nout << " stopped by " << WSTOPSIG(status) << "\n";
|
||||
}
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
|
@ -1708,15 +1717,24 @@ posix_create_process() {
|
|||
// its process. Report an error condition.
|
||||
nout << "Python process stopped immediately.\n";
|
||||
if (WIFEXITED(status)) {
|
||||
nout << " exited normally, status = "
|
||||
<< WEXITSTATUS(status) << "\n";
|
||||
int code = WEXITSTATUS(status);
|
||||
|
||||
nout << " exited normally, status = " << code << "\n";
|
||||
if (code != 0) {
|
||||
_exit(code);
|
||||
}
|
||||
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
nout << " signalled by " << WTERMSIG(status) << ", core = "
|
||||
nout << " signalled by " << WTERMSIG(status) << ", core = "
|
||||
<< WCOREDUMP(status) << "\n";
|
||||
|
||||
// This seems to be a popular shell convention.
|
||||
_exit(128 + WTERMSIG(status));
|
||||
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
nout << " stopped by " << WSTOPSIG(status) << "\n";
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
|
@ -1798,10 +1816,12 @@ p3dpython_thread_run() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(),
|
||||
_input_handle, _output_handle, _log_pathname.c_str(),
|
||||
_interactive_console)) {
|
||||
int status = run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(),
|
||||
_input_handle, _output_handle, _log_pathname.c_str(),
|
||||
_interactive_console);
|
||||
if (status != 0) {
|
||||
nout << "Failure on startup.\n";
|
||||
_exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,16 +19,17 @@
|
|||
// Function: run_p3dpython
|
||||
// Description: This externally-visible function is the main entry
|
||||
// point to this DLL, and it starts the whole thing
|
||||
// running. Returns true on success, false on failure.
|
||||
// running. Returns the exit status, which will be
|
||||
// 0 on success, 1 or otherwise on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
int
|
||||
run_p3dpython(const char *program_name, const char *archive_file,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
const char *log_pathname, bool interactive_console) {
|
||||
P3DPythonRun::_global_ptr =
|
||||
new P3DPythonRun(program_name, archive_file, input_handle, output_handle,
|
||||
P3DPythonRun::_global_ptr =
|
||||
new P3DPythonRun(program_name, archive_file, input_handle, output_handle,
|
||||
log_pathname, interactive_console);
|
||||
bool result = P3DPythonRun::_global_ptr->run_python();
|
||||
int result = P3DPythonRun::_global_ptr->run_python();
|
||||
delete P3DPythonRun::_global_ptr;
|
||||
P3DPythonRun::_global_ptr = NULL;
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@
|
|||
#define EXPCL_P3DPYTHON
|
||||
#endif
|
||||
|
||||
typedef bool
|
||||
typedef int
|
||||
run_p3dpython_func(const char *program_name, const char *archive_file,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
const char *log_pathname, bool interactive_console);
|
||||
|
||||
extern "C" EXPCL_P3DPYTHON bool
|
||||
extern "C" EXPCL_P3DPYTHON int
|
||||
run_p3dpython(const char *program_name, const char *archive_file,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
FHandle input_handle, FHandle output_handle,
|
||||
const char *log_pathname, bool interactive_console);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue