From ab3e13403fe287d434005b823c1149054f841a7f Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 26 Oct 2009 20:19:19 +0000 Subject: [PATCH] some small fixes, starting _web_hostname integration --- direct/src/plugin/p3dInstance.cxx | 36 ++++++++++++ direct/src/plugin/p3dInstance.h | 1 + direct/src/plugin/p3dInstanceManager.cxx | 3 +- direct/src/plugin/p3dSession.cxx | 72 +++++++++++++++++++++++- direct/src/plugin_activex/PPLogger.cpp | 3 +- direct/src/plugin_npapi/startup.cxx | 3 +- 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index f3d7cbc6a1..4a88b98cde 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -502,6 +502,7 @@ get_panda_script_object() const { //////////////////////////////////////////////////////////////////// void P3DInstance:: set_browser_script_object(P3D_object *browser_script_object) { + nout << "set_browser_script_object\n"; if (browser_script_object != _browser_script_object) { P3D_OBJECT_XDECREF(_browser_script_object); _browser_script_object = browser_script_object; @@ -513,6 +514,41 @@ set_browser_script_object(P3D_object *browser_script_object) { send_browser_script_object(); } } + + // Query the location hostname. We'll use this to limit access to + // the scripting interfaces for a particular p3d file. + _web_hostname = ""; + if (_browser_script_object != NULL) { + P3D_object *location = P3D_OBJECT_GET_PROPERTY(_browser_script_object, "location"); + if (location != NULL) { + P3D_object *hostname = P3D_OBJECT_GET_PROPERTY(location, "hostname"); + if (hostname != NULL) { + int size = P3D_OBJECT_GET_STRING(hostname, NULL, 0); + char *buffer = new char[size]; + P3D_OBJECT_GET_STRING(hostname, buffer, size); + _web_hostname = string(buffer, size); + delete [] buffer; + + P3D_OBJECT_DECREF(hostname); + } + + P3D_object *protocol = P3D_OBJECT_GET_PROPERTY(location, "protocol"); + if (protocol != NULL) { + int size = P3D_OBJECT_GET_STRING(protocol, NULL, 0); + char *buffer = new char[size]; + P3D_OBJECT_GET_STRING(protocol, buffer, size); + if (string(buffer, size) == "file:") { + _web_hostname = "local"; + } + delete [] buffer; + P3D_OBJECT_DECREF(protocol); + } + + P3D_OBJECT_DECREF(location); + } + } + + nout << "_web_hostname is " << _web_hostname << "\n"; } diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index eb0b0e69b3..049f2eb6ff 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -193,6 +193,7 @@ private: P3D_request_ready_func *_func; P3D_object *_browser_script_object; P3DMainObject *_panda_script_object; + string _web_hostname; P3DTemporaryFile *_temp_p3d_filename; diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index fb66977e44..9469b016fa 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -236,7 +236,8 @@ initialize(const string &contents_filename, const string &host_url, _log_pathname = _log_directory; _log_pathname += _log_basename; _log_pathname += ".log"; - + + logfile.close(); logfile.clear(); logfile.open(_log_pathname.c_str(), ios::out | ios::trunc); if (logfile) { diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 2f68e21290..ace57f41b7 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -787,8 +787,11 @@ start_p3dpython(P3DInstance *inst) { if (_p3dpython_exe.empty()) { _p3dpython_exe = _python_root_dir + "/p3dpython"; #ifdef __APPLE__ - // On OSX, run from the packaged bundle. - _p3dpython_exe = _python_root_dir + "/P3DPython.app/Contents/MacOS/p3dpython"; + // On OSX, run from the packaged bundle, if it exists. + string bundle_exe = _python_root_dir + "/P3DPython.app/Contents/MacOS/p3dpython"; + if (access(bundle_exe.c_str(), X_OK) == 0) { + _p3dpython_exe = bundle_exe; + } #endif } #ifdef _WIN32 @@ -1065,6 +1068,13 @@ start_p3dpython(P3DInstance *inst) { // Fall back to running it in a sub-thread within the same // process. This isn't nearly as good, but I guess it's better // than nothing. +#ifndef _WIN32 + // Let's only do this sub-thread fallback on Windows. On Mac and + // Linux, just fail. + set_failed(); + return; +#endif // _WIN32 + INIT_THREAD(_p3dpython_thread); SPAWN_THREAD(_p3dpython_thread, p3dpython_thread_run, this); _p3dpython_one_process = true; @@ -1377,6 +1387,12 @@ win_create_process() { //////////////////////////////////////////////////////////////////// int P3DSession:: posix_create_process() { + // If the program file doesn't exist or isn't executable, don't even + // bother to try. + if (access(_p3dpython_exe.c_str(), X_OK) != 0) { + return -1; + } + // Fork and exec. pid_t child = fork(); if (child < 0) { @@ -1444,7 +1460,57 @@ posix_create_process() { close(_input_handle); close(_output_handle); - return child; + // Let's wait a few milliseconds and see if the child is going to + // immediately exit with a failure status. This isn't 100% + // reliable, but it's a lot easier than sending back a "yes I + // successfully started the program" message. Maybe I'll put in the + // more reliable test later. + + struct timeval start; + gettimeofday(&start, NULL); + int start_ms = start.tv_sec * 1000 + start.tv_usec / 1000; + + int status; + pid_t result = waitpid(child, &status, WNOHANG); + while (result != child) { + if (result == -1) { + perror("waitpid"); + break; + } + + struct timeval now; + gettimeofday(&now, NULL); + int now_ms = now.tv_sec * 1000 + now.tv_usec / 1000; + int elapsed = now_ms - start_ms; + if (elapsed > 100) { + // OK, we've waited, and the child process is still alive. + // Assume it will stay that way. + nout << "child still alive after " << elapsed << " ms\n"; + return child; + } + + // Yield the timeslice and wait some more. + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1; + select(0, NULL, NULL, NULL, &tv); + result = waitpid(child, &status, WNOHANG); + } + + // The child process died for some reason; maybe it couldn't exec() + // its process. Report an error condition. + nout << "Python process stopped immediately.\n"; + if (WIFEXITED(status)) { + nout << " exited normally, status = " + << WEXITSTATUS(status) << "\n"; + } else if (WIFSIGNALED(status)) { + nout << " signalled by " << WTERMSIG(status) << ", core = " + << WCOREDUMP(status) << "\n"; + } else if (WIFSTOPPED(status)) { + nout << " stopped by " << WSTOPSIG(status) << "\n"; + } + + return -1; } #endif // _WIN32 diff --git a/direct/src/plugin_activex/PPLogger.cpp b/direct/src/plugin_activex/PPLogger.cpp index 17540707fe..d9d704a64a 100644 --- a/direct/src/plugin_activex/PPLogger.cpp +++ b/direct/src/plugin_activex/PPLogger.cpp @@ -131,7 +131,8 @@ void PPLogger::Open( const std::string &rootDir ) std::string log_pathname = log_directory; log_pathname += log_basename; log_pathname += ".log"; - + + m_logfile.close(); m_logfile.clear(); m_logfile.open(log_pathname.c_str(), std::ios::out | std::ios::trunc); m_logfile.setf(std::ios::unitbuf); diff --git a/direct/src/plugin_npapi/startup.cxx b/direct/src/plugin_npapi/startup.cxx index 668cbb0dcf..9028b18169 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -74,7 +74,8 @@ open_logfile() { string log_pathname = log_directory; log_pathname += log_basename; log_pathname += ".log"; - + + logfile.close(); logfile.clear(); logfile.open(log_pathname.c_str(), ios::out | ios::trunc); logfile.setf(ios::unitbuf);