From 1415193b5ea446377729988c29f47ce2d357e41f Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 31 Aug 2009 22:25:32 +0000 Subject: [PATCH] separate out p3dpython.exe and libp3dpython.dll --- direct/src/plugin/Sources.pp | 37 ++++++- direct/src/plugin/p3dPythonMain.cxx | 150 ++-------------------------- direct/src/plugin/p3dSession.cxx | 82 +++++---------- 3 files changed, 67 insertions(+), 202 deletions(-) diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index a0a35028c4..686acbb2c9 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -93,10 +93,18 @@ #end lib_target + #begin lib_target +// ***** +// Note! This lib is used to run P3DPythonRun within the parent +// (browser) process, instead of forking a child. This seems like +// it's going to be a bad idea in the long term. This lib remains +// for now as an experiment, but it will likely be removed very soon. +// **** #define BUILD_TARGET $[HAVE_PYTHON] #define USE_PACKAGES tinyxml python - #define TARGET p3dpython + #define TARGET libp3dpython + #define LIB_PREFIX #define OTHER_LIBS \ dtoolutil:c dtoolbase:c dtool:m \ @@ -122,12 +130,35 @@ #begin bin_target #define BUILD_TARGET $[HAVE_PYTHON] + #define USE_PACKAGES tinyxml python #define TARGET p3dpython + #define OTHER_LIBS \ + dtoolutil:c dtoolbase:c dtool:m \ + interrogatedb:c dconfig:c dtoolconfig:m \ + express:c pandaexpress:m \ + prc:c pstatclient:c pandabase:c linmath:c putil:c \ + pipeline:c event:c nativenet:c net:c panda:m + #define SOURCES \ + binaryXml.cxx binaryXml.h \ fhandle.h \ - p3dPythonMain.cxx \ - run_p3dpython.h + handleStream.cxx handleStream.h handleStream.I \ + handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \ + p3d_lock.h p3d_plugin.h \ + p3d_plugin_config.h \ + p3dCInstance.cxx \ + p3dCInstance.h p3dCInstance.I \ + p3dPythonRun.cxx p3dPythonRun.h p3dPythonRun.I \ + run_p3dpython.h run_p3dpython.cxx + + #define SOURCES $[SOURCES] \ + p3dPythonMain.cxx + + // If you have to link with a static Python library, define it here. + #define EXTRA_LIBS $[EXTRA_P3DPYTHON_LIBS] + + #define WIN_SYS_LIBS user32.lib #end bin_target #begin static_lib_target diff --git a/direct/src/plugin/p3dPythonMain.cxx b/direct/src/plugin/p3dPythonMain.cxx index 68c6bec259..ad479db2cf 100644 --- a/direct/src/plugin/p3dPythonMain.cxx +++ b/direct/src/plugin/p3dPythonMain.cxx @@ -19,29 +19,16 @@ #include // strrchr using namespace std; -#ifndef _WIN32 -#include -#endif - -#ifdef _WIN32 -static const string dll_ext = ".dll"; -#elif defined(__APPLE__) -static const string dll_ext = ".dylib"; -#else -static const string dll_ext = ".so"; -#endif - //////////////////////////////////////////////////////////////////// // Function: main -// Description: This is a trivial main() function that loads and runs -// libp3dpython.dll. It's used to build p3dpython.exe, +// Description: This is a trivial main() function that invokes +// P3DPythonRun. It's used to build p3dpython.exe, // which is the preferred way to run Python in a child // process, as a separate executable. //////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { const char *program_name = argv[0]; - const char *dll_file = NULL; const char *archive_file = NULL; const char *input_handle_str = NULL; const char *output_handle_str = NULL; @@ -49,27 +36,19 @@ main(int argc, char *argv[]) { const char *interactive_console_str = NULL; if (argc > 1) { - dll_file = argv[1]; + archive_file = argv[1]; } if (argc > 2) { - archive_file = argv[2]; + input_handle_str = argv[2]; } if (argc > 3) { - input_handle_str = argv[3]; + output_handle_str = argv[3]; } if (argc > 4) { - output_handle_str = argv[4]; + error_handle_str = argv[4]; } if (argc > 5) { - error_handle_str = argv[5]; - } - if (argc > 6) { - interactive_console_str = argv[6]; - } - - if (dll_file == NULL || *dll_file == '\0') { - cerr << "No libp3dpython filename specified on command line.\n"; - return 1; + interactive_console_str = argv[5]; } if (archive_file == NULL || *archive_file == '\0') { @@ -118,121 +97,6 @@ main(int argc, char *argv[]) { << ", " << error_handle << "\n"; cerr << "interactive_console = " << interactive_console << "\n"; - // For some vague idea of security, we insist that this program can - // only run libp3dpython.dll: you can't use it to load just any - // arbitrary DLL on the system. Of course, if you're successfully - // running this program in the first place, you probably don't need - // any help to load an arbitrary DLL, but whatever. - - // Find the basename of the dll_file. - const char *slash = strrchr(dll_file, '/'); -#ifdef _WIN32 - const char *backslash = strrchr(dll_file, '\\'); - if (backslash != NULL && (slash == NULL || backslash > slash)) { - slash = backslash; - } -#endif - string basename; - if (slash == NULL) { - basename = dll_file; - } else { - //dirname = string(dll_file, slash - dll_file); - basename = (slash + 1); - } - - string expected_basename = "libp3dpython" + dll_ext; - if (basename != expected_basename) { - cerr << dll_file << " does not name " << expected_basename << "\n"; - return 1; - } - - // Everything checks out. Load and run the library. - -#ifdef _WIN32 - SetErrorMode(0); - HMODULE module = LoadLibrary(dll_file); - if (module == NULL) { - // Couldn't load the DLL. - cerr << "Couldn't load " << dll_file << "\n"; - return 1; - } - - #define get_func GetProcAddress - - // Get the default values for the communication handles, if we - // weren't given specific handles. - if (input_handle == invalid_fhandle) { - input_handle = GetStdHandle(STD_INPUT_HANDLE); - - // Close the system input handle, so application code won't - // accidentally read from our private input stream. - if (!SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE)) { - cerr << "unable to reset input handle\n"; - } - } - - if (output_handle == invalid_fhandle) { - output_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // Close the system output handle, so application code won't - // accidentally write to our private output stream. - if (!SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE)) { - cerr << "unable to reset input handle\n"; - } - } - - // No matter what error handle we were given, make it - // STD_ERROR_HANDLE. - if (error_handle == invalid_fhandle) { - error_handle = GetStdHandle(STD_ERROR_HANDLE); - } else { - SetStdHandle(STD_ERROR_HANDLE, error_handle); - } - -#else // _WIN32 - // Posix case. - void *module = dlopen(dll_file, RTLD_LAZY | RTLD_LOCAL); - if (module == NULL) { - // Couldn't load the .so. - cerr << "Couldn't load " << dll_file << "\n"; - char *message = dlerror(); - if (message != (char *)NULL) { - cerr << message << "\n"; - } else { - cerr << "No error.\n"; - } - return 1; - } - - #define get_func dlsym - - // Get the default values for the communication handles, if we - // weren't given specific handles. - if (input_handle == invalid_fhandle) { - input_handle = STDIN_FILENO; - } - - if (output_handle == invalid_fhandle) { - output_handle = STDOUT_FILENO; - } - - // No matter what error handle we were given, make it STDERR_FILENO. - if (error_handle == invalid_fhandle) { - error_handle = STDERR_FILENO; - } else if (error_handle != STDERR_FILENO) { - dup2(error_handle, STDERR_FILENO); - close(error_handle); - error_handle = STDERR_FILENO; - } - -#endif // _WIN32 - - run_p3dpython_func *run_p3dpython = (run_p3dpython_func *)get_func(module, "run_p3dpython"); - if (run_p3dpython == NULL) { - cerr << "Couldn't find run_p3dpython\n"; - return 1; - } - if (!run_p3dpython(program_name, archive_file, input_handle, output_handle, error_handle, interactive_console)) { cerr << "Failure on startup.\n"; diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 1cced8eeab..ea39ea025f 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -747,51 +747,16 @@ start_p3dpython(P3DInstance *inst) { << "PRC_PATH set to: " << prc_path << "\n"; } - // Get the name of the executable and dynamic library to run. - // Ideally, we'll run the executable successfully, in a sub-process; - // this will in turn load and run the dynamic library. If that - // fails for some reason, we can fall back to loading and running - // the library directly. - _p3dpython_exe = _python_root_dir + "/p3dpython"; + // Get the name of the executable to run. Ideally, we'll run the + // executable successfully, in a sub-process; this will in turn load + // and run the dynamic library. If that fails for some reason, we + // can fall back to loading and running the library directly. + _p3dpython_exe = P3D_PLUGIN_P3DPYTHON; + if (_p3dpython_exe.empty()) { + _p3dpython_exe = _python_root_dir + "/p3dpython"; #ifdef _WIN32 - _p3dpython_exe += ".exe"; + _p3dpython_exe += ".exe"; #endif - - _p3dpython_dll = P3D_PLUGIN_P3DPYTHON; - if (_p3dpython_dll.empty()) { - _p3dpython_dll = _python_root_dir + "/libp3dpython"; -#ifdef _WIN32 - _p3dpython_dll += ".dll"; -#elif defined(__APPLE__) - _p3dpython_dll += ".dylib"; -#else - _p3dpython_dll += ".so"; -#endif - } else { - // We have a custom path to libp3dpython.dylib etc., for - // development. - -#ifdef __APPLE__ - // For some bizarre reason, Apple's dlopen() goes out of its way to - // ignore whatever full path you specify, and always searches for - // the file's basename along $DYLD_LIBRARY_PATH. Weird. To work - // around this and load the full path we're actually asking for, we - // have to ensure that our desired path appears first on - // $DYLD_LIBRARY_PATH. - - // This may also inadvertently put other (incorrect) files first - // on the path, but presumably this won't cause too much trouble, - // since the user is in development mode anyway and maybe won't - // mind. - size_t slash = _p3dpython_dll.rfind('/'); - if (slash != string::npos) { - string dirname = _p3dpython_dll.substr(0, slash); - cerr << "dirname is " << dirname << "\n"; - - dyld_path = dirname + ":" + dyld_path; - cerr << "dyld_path is " << dyld_path << "\n"; - } -#endif // __APPLE__ } // Populate the new process' environment. @@ -998,8 +963,7 @@ start_p3dpython(P3DInstance *inst) { // to p3dpython. _mf_filename = inst->_panda3d->get_archive_file_pathname(); - nout << "Attempting to start python from " << _p3dpython_exe - << " and " << _p3dpython_dll << "\n"; + nout << "Attempting to start python from " << _p3dpython_exe << "\n"; bool started_p3dpython; if (one_process) { @@ -1225,10 +1189,10 @@ win_create_process() { // Construct the command-line string, containing the quoted // command-line arguments. ostringstream stream; - stream << "\"" << _p3dpython_exe << "\" \"" << _p3dpython_dll - << "\" \"" << _mf_filename << "\" \"" << _input_handle - << "\" \"" << _output_handle << "\" \"" << _error_handle - << "\" \"" << _interactive_console << "\""; + stream << "\"" << _p3dpython_exe << "\" \"" << _mf_filename + << "\" \"" << _input_handle << "\" \"" << _output_handle + << "\" \"" << _error_handle << "\" \"" << _interactive_console + << "\""; // I'm not sure why CreateProcess wants a non-const char pointer for // its command-line string, but I'm not taking chances. It gets a @@ -1330,8 +1294,7 @@ posix_create_process() { error_handle_stream << _error_handle; string error_handle_str = error_handle_stream.str(); - execle(_p3dpython_exe.c_str(), - _p3dpython_exe.c_str(), _p3dpython_dll.c_str(), + execle(_p3dpython_exe.c_str(), _p3dpython_exe.c_str(), _mf_filename.c_str(), input_handle_str.c_str(), output_handle_str.c_str(), error_handle_str.c_str(), _interactive_console ? "1" : "0", (char *)0, &ptrs[0]); @@ -1386,12 +1349,14 @@ p3dpython_thread_run() { } // Now load the library. + string libp3dpython = _python_root_dir + "/libp3dpython"; #ifdef _WIN32 + libp3dpython += ".dll"; SetErrorMode(0); - HMODULE module = LoadLibrary(_p3dpython_dll.c_str()); + HMODULE module = LoadLibrary(libp3dpython.c_str()); if (module == NULL) { // Couldn't load the DLL. - nout << "Couldn't load " << _p3dpython_dll << "\n"; + nout << "Couldn't load " << libp3dpython << "\n"; return; } @@ -1399,10 +1364,15 @@ p3dpython_thread_run() { #else // _WIN32 // Posix case. - void *module = dlopen(_p3dpython_dll.c_str(), RTLD_LAZY | RTLD_LOCAL); + #ifdef __APPLE__ + libp3dpython += ".dylib"; + #else + libp3dpython += ".so"; + #endif + void *module = dlopen(libp3dpython.c_str(), RTLD_LAZY | RTLD_LOCAL); if (module == NULL) { // Couldn't load the .so. - nout << "Couldn't load " << _p3dpython_dll << "\n"; + nout << "Couldn't load " << libp3dpython << "\n"; return; } @@ -1416,7 +1386,7 @@ p3dpython_thread_run() { return; } - if (!run_p3dpython(_p3dpython_dll.c_str(), _mf_filename.c_str(), + if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(), _input_handle, _output_handle, _error_handle, _interactive_console)) { nout << "Failure on startup.\n";