diff options
author | Cy Schubert <cy@FreeBSD.org> | 2019-12-28 05:27:06 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2019-12-28 05:27:06 +0000 |
commit | e2fe726866d062155f6b1aae749375475ef19191 (patch) | |
tree | fe6b00611d5c987d2c12c32063891ae19295ffeb /pythonmod | |
parent | 366b94c4a9552acfb560d3234aea0955ebc1eb8e (diff) |
Diffstat (limited to 'pythonmod')
-rw-r--r-- | pythonmod/examples/calc.py | 8 | ||||
-rw-r--r-- | pythonmod/interface.i | 7 | ||||
-rw-r--r-- | pythonmod/pythonmod.c | 85 |
3 files changed, 65 insertions, 35 deletions
diff --git a/pythonmod/examples/calc.py b/pythonmod/examples/calc.py index 3230e37e3eea6..8c15f50b9d75c 100644 --- a/pythonmod/examples/calc.py +++ b/pythonmod/examples/calc.py @@ -45,9 +45,13 @@ def operate(id, event, qstate, qdata): if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS): - if qstate.qinfo.qname_str.endswith("._calc_.cz."): + if qstate.qinfo.qname_str.endswith("._calc_.cz.") and not ("__" in qstate.qinfo.qname_str): try: - res = eval(''.join(qstate.qinfo.qname_list[0:-3])) + # the second and third argument to eval attempt to restrict + # functions and variables available to stop code execution + # but it may not be safe either. This is why __ substrings + # are excluded from evaluation. + res = eval(''.join(qstate.qinfo.qname_list[0:-3]),{"__builtins__":None},{}) except: res = "exception" diff --git a/pythonmod/interface.i b/pythonmod/interface.i index 14f0299eeb575..c02ebaf951d0b 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -4,6 +4,9 @@ %begin %{ /* store state of warning output, restored at later pop */ #pragma GCC diagnostic push +/* ignore warnings for pragma below, where for older GCC it can produce a + warning if the cast-function-type warning is absent. */ +#pragma GCC diagnostic ignored "-Wpragmas" /* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */ #pragma GCC diagnostic ignored "-Wcast-function-type" %} @@ -1011,7 +1014,7 @@ struct config_file { char* control_key_file; char* control_cert_file; int do_daemonize; - char* python_script; + struct config_strlist* python_script; }; /* ************************************************************************************ * @@ -1106,6 +1109,7 @@ struct delegpt { %rename ("MODULE_STATE_INITIAL") "module_state_initial"; %rename ("MODULE_WAIT_REPLY") "module_wait_reply"; %rename ("MODULE_WAIT_MODULE") "module_wait_module"; +%rename ("MODULE_RESTART_NEXT") "module_restart_next"; %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery"; %rename ("MODULE_ERROR") "module_error"; %rename ("MODULE_FINISHED") "module_finished"; @@ -1114,6 +1118,7 @@ enum module_ext_state { module_state_initial = 0, module_wait_reply, module_wait_module, + module_restart_next, module_wait_subquery, module_error, module_finished diff --git a/pythonmod/pythonmod.c b/pythonmod/pythonmod.c index 9009a28daaa06..9006429efff52 100644 --- a/pythonmod/pythonmod.c +++ b/pythonmod/pythonmod.c @@ -65,6 +65,15 @@ typedef void* PyGILState_STATE; #endif /** + * counter for python module instances + * incremented by pythonmod_init(...) + */ +int py_mod_count = 0; + +/** Python main thread */ +PyThreadState* mainthr; + +/** * Global state for the module. */ struct pythonmod_env { @@ -72,8 +81,6 @@ struct pythonmod_env { /** Python script filename. */ const char* fname; - /** Python main thread */ - PyThreadState* mainthr; /** Python module. */ PyObject* module; @@ -242,14 +249,17 @@ cleanup: int pythonmod_init(struct module_env* env, int id) { + int py_mod_idx = py_mod_count++; + /* Initialize module */ FILE* script_py = NULL; PyObject* py_init_arg, *res; PyGILState_STATE gil; - int init_standard = 1; + int init_standard = 1, i = 0; #if PY_MAJOR_VERSION < 3 PyObject* PyFileObject = NULL; #endif + struct config_strlist* cfg_item = env->cfg->python_script; struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env)); if (!pe) @@ -261,14 +271,21 @@ int pythonmod_init(struct module_env* env, int id) env->modinfo[id] = (void*) pe; /* Initialize module */ - pe->fname = env->cfg->python_script; + pe->fname=NULL; i = 0; + while (cfg_item!=NULL) { + if (py_mod_idx==i++) { + pe->fname=cfg_item->str; + break; + } + cfg_item = cfg_item->next; + } if(pe->fname==NULL || pe->fname[0]==0) { - log_err("pythonmod: no script given."); + log_err("pythonmod[%d]: no script given.", py_mod_idx); return 0; } /* Initialize Python libraries */ - if (!Py_IsInitialized()) + if (py_mod_count==1 && !Py_IsInitialized()) { #if PY_MAJOR_VERSION >= 3 wchar_t progname[8]; @@ -284,29 +301,31 @@ int pythonmod_init(struct module_env* env, int id) Py_Initialize(); PyEval_InitThreads(); SWIG_init(); - pe->mainthr = PyEval_SaveThread(); + 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; + if (py_mod_count==1) { + /* 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 */ @@ -328,8 +347,8 @@ int pythonmod_init(struct module_env* env, int id) /* Load file */ pe->module = PyImport_AddModule("__main__"); pe->dict = PyModule_GetDict(pe->module); - pe->data = Py_None; - Py_INCREF(pe->data); + pe->data = PyDict_New(); + Py_XINCREF(pe->data); PyModule_AddObject(pe->module, "mod_env", pe->data); /* TODO: deallocation of pe->... if an error occurs */ @@ -352,6 +371,7 @@ int pythonmod_init(struct module_env* env, int id) (void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input); log_py_err(); PyGILState_Release(gil); + fclose(script_py); return 0; } #if PY_MAJOR_VERSION < 3 @@ -440,9 +460,11 @@ void pythonmod_deinit(struct module_env* env, int id) Py_XDECREF(pe->data); PyGILState_Release(gil); - PyEval_RestoreThread(pe->mainthr); - Py_Finalize(); - pe->mainthr = NULL; + if(--py_mod_count==0) { + PyEval_RestoreThread(mainthr); + Py_Finalize(); + mainthr = NULL; + } } pe->fname = NULL; free(pe); @@ -500,8 +522,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate)); /* Initialize per query data */ - pq->data = Py_None; - Py_INCREF(pq->data); + pq->data = PyDict_New(); } /* Call operate */ |