RunPythonFileAction::RunPythonFileAction(const ParameterValueMap ¶meters) : RunPythonAction(parameters) { // Converting to boost::filesystem::path first buys us some useful path expansion and validation const std::string filename(boost::filesystem::path(parameters[PATH]).string()); std::FILE *fp = std::fopen(filename.c_str(), "r"); if (!fp) { throw SimpleException(M_FILE_MESSAGE_DOMAIN, "Unable to open Python file", strerror(errno)); } BOOST_SCOPE_EXIT(fp) { std::fclose(fp); } BOOST_SCOPE_EXIT_END ScopedGILAcquire sga; struct _node *node = PyParser_SimpleParseFile(fp, filename.c_str(), Py_file_input); BOOST_SCOPE_EXIT(node) { PyNode_Free(node); } BOOST_SCOPE_EXIT_END if (!node || !(codeObject = PyNode_Compile(node, filename.c_str()))) { throw PythonException("Python compilation failed"); } }
PyObject * PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals, PyObject *locals, int closeit) { node *n = PyParser_SimpleParseFile(fp, filename, start); if (closeit) fclose(fp); return run_err_node(n, filename, globals, locals); }
int pythonmod_init(struct module_env* env, int id) { /* Initialize module */ FILE* script_py = NULL; PyObject* py_init_arg, *res; PyGILState_STATE gil; int init_standard = 1; #if PY_MAJOR_VERSION < 3 PyObject* PyFileObject = NULL; #endif struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env)); if (!pe) { log_err("pythonmod: malloc failure"); return 0; } env->modinfo[id] = (void*) pe; /* Initialize module */ pe->fname = env->cfg->python_script; if(pe->fname==NULL || pe->fname[0]==0) { log_err("pythonmod: no script given."); return 0; } /* Initialize Python libraries */ if (!Py_IsInitialized()) { #if PY_MAJOR_VERSION >= 3 wchar_t progname[8]; mbstowcs(progname, "unbound", 8); #else char *progname = "unbound"; #endif Py_SetProgramName(progname); Py_NoSiteFlag = 1; #if PY_MAJOR_VERSION >= 3 PyImport_AppendInittab(SWIG_name, (void*)SWIG_init); #endif Py_Initialize(); PyEval_InitThreads(); SWIG_init(); pe->mainthr = PyEval_SaveThread(); } gil = PyGILState_Ensure(); /* Initialize Python */ PyRun_SimpleString("import sys \n"); PyRun_SimpleString("sys.path.append('.') \n"); if(env->cfg->directory && env->cfg->directory[0]) { char wdir[1524]; snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n", env->cfg->directory); PyRun_SimpleString(wdir); } PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n"); PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n"); PyRun_SimpleString("import distutils.sysconfig \n"); PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n"); if (PyRun_SimpleString("from unboundmodule import *\n") < 0) { log_err("pythonmod: cannot initialize core module: unboundmodule.py"); PyGILState_Release(gil); return 0; } /* Check Python file load */ /* uses python to open the file, this works on other platforms, * eg. Windows, to open the file in the correct mode for python */ #if PY_MAJOR_VERSION < 3 PyFileObject = PyFile_FromString((char*)pe->fname, "r"); script_py = PyFile_AsFile(PyFileObject); #else script_py = _Py_fopen(pe->fname, "r"); #endif if (script_py == NULL) { log_err("pythonmod: can't open file %s for reading", pe->fname); PyGILState_Release(gil); return 0; } /* Load file */ pe->module = PyImport_AddModule("__main__"); pe->dict = PyModule_GetDict(pe->module); pe->data = Py_None; Py_INCREF(pe->data); PyModule_AddObject(pe->module, "mod_env", pe->data); /* TODO: deallocation of pe->... if an error occurs */ if (PyRun_SimpleFile(script_py, pe->fname) < 0) { log_err("pythonmod: can't parse Python script %s", pe->fname); /* print the error to logs too, run it again */ fseek(script_py, 0, SEEK_SET); /* we don't run the file, like this, because then side-effects * s = PyRun_File(script_py, pe->fname, Py_file_input, * PyModule_GetDict(PyImport_AddModule("__main__")), pe->dict); * could happen (again). Instead we parse the file again to get * the error string in the logs, for when the daemon has stderr * removed. SimpleFile run already printed to stderr, for then * this is called from unbound-checkconf or unbound -dd the user * has a nice formatted error. */ /* ignore the NULL return of _node, it is NULL due to the parse failure * that we are expecting */ (void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input); log_py_err(); PyGILState_Release(gil); return 0; } #if PY_MAJOR_VERSION < 3 Py_XDECREF(PyFileObject); #else fclose(script_py); #endif if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL) { init_standard = 0; if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL) { log_err("pythonmod: function init is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } } if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL) { log_err("pythonmod: function deinit is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL) { log_err("pythonmod: function operate is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL) { log_err("pythonmod: function inform_super is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } if (init_standard) { py_init_arg = SWIG_NewPointerObj((void*) env, SWIGTYPE_p_module_env, 0); } else { py_init_arg = SWIG_NewPointerObj((void*) env->cfg, SWIGTYPE_p_config_file, 0); } res = PyObject_CallFunction(pe->func_init, "iO", id, py_init_arg); if (PyErr_Occurred()) { log_err("pythonmod: Exception occurred in function init"); log_py_err(); Py_XDECREF(res); Py_XDECREF(py_init_arg); PyGILState_Release(gil); return 0; } Py_XDECREF(res); Py_XDECREF(py_init_arg); PyGILState_Release(gil); return 1; }
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) { #ifdef UWSGI_PYPY uwsgi_log("import by filename is currently not supported on PyPy !!!\n"); return NULL; #else FILE *pyfile; struct _node *py_file_node = NULL; PyObject *py_compiled_node, *py_file_module; int is_a_package = 0; struct stat pystat; char *real_filename = filename; if (!uwsgi_check_scheme(filename)) { pyfile = fopen(filename, "r"); if (!pyfile) { uwsgi_log("failed to open python file %s\n", filename); return NULL; } if (fstat(fileno(pyfile), &pystat)) { uwsgi_error("fstat()"); return NULL; } if (S_ISDIR(pystat.st_mode)) { is_a_package = 1; fclose(pyfile); real_filename = uwsgi_concat2(filename, "/__init__.py"); pyfile = fopen(real_filename, "r"); if (!pyfile) { uwsgi_error_open(real_filename); free(real_filename); return NULL; } } py_file_node = PyParser_SimpleParseFile(pyfile, real_filename, Py_file_input); if (!py_file_node) { PyErr_Print(); uwsgi_log("failed to parse file %s\n", real_filename); if (is_a_package) free(real_filename); fclose(pyfile); return NULL; } fclose(pyfile); } else { int pycontent_size = 0; char *pycontent = uwsgi_open_and_read(filename, &pycontent_size, 1, NULL); if (pycontent) { py_file_node = PyParser_SimpleParseString(pycontent, Py_file_input); if (!py_file_node) { PyErr_Print(); uwsgi_log("failed to parse url %s\n", real_filename); return NULL; } } } py_compiled_node = (PyObject *) PyNode_Compile(py_file_node, real_filename); if (!py_compiled_node) { PyErr_Print(); uwsgi_log("failed to compile python file %s\n", real_filename); return NULL; } if (is_a_package) { py_file_module = PyImport_AddModule(name); if (py_file_module) { PyModule_AddObject(py_file_module, "__path__", Py_BuildValue("[O]", PyString_FromString(filename))); } free(real_filename); } py_file_module = PyImport_ExecCodeModule(name, py_compiled_node); if (!py_file_module) { PyErr_Print(); return NULL; } Py_DECREF(py_compiled_node); return py_file_module; #endif }