From c5ed603b5cf9da0712f0c1411b77b7eed4c38548 Mon Sep 17 00:00:00 2001 From: yangruochen Date: Thu, 19 Mar 2020 17:29:16 +0800 Subject: [PATCH 1/2] support python3 --- configure.ac | 26 +++++++----- gmond/modules/python/mod_python.c | 70 ++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 86ea1eec2..4aa441ba2 100644 --- a/configure.ac +++ b/configure.ac @@ -319,21 +319,26 @@ if test x"$enable_python" = xyes; then if test -n "$PYTHON_BIN"; then # find out python version AC_MSG_CHECKING(Python version) - PyVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:3]'`] - PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:1]'`] + PyVERSION=`$PYTHON_BIN -c ['import sys; print(sys.version[:3])'`] + PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print(sys.version[:1])'`] AC_MSG_RESULT($PyVERSION) PYTHON_VERSION=$PyVERSION AC_SUBST(PYTHON_VERSION) - PyEXEC_INSTALLDIR=`$PYTHON_BIN -c "import sys; print sys.exec_prefix"` - if test -f "$PyEXEC_INSTALLDIR/include/python/Python.h"; then - PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python" + PyEXEC_INSTALLDIR=`$PYTHON_BIN -c "import sys; print(sys.exec_prefix)"` + if test -f "$PyEXEC_INSTALLDIR/include/python$PyVERSION/Python.h"; then + PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python$PyVERSION" else - if test -f "$PyEXEC_INSTALLDIR/include/python$PyVERSION/Python.h"; then - PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python$PyVERSION" + if test -f $PyEXEC_INSTALLDIR'/include/python'$PyVERSION'm/Python.h'; then + PYTHON_VERSION=$PYTHON_VERSION'm' + PYTHON_INCLUDES='-I'$PyEXEC_INSTALLDIR'/include/python'$PyVERSION'm' else - PYTHON_INCLUDES="" - enable_python="no" + if test -f "$PyEXEC_INSTALLDIR/include/python/Python.h"; then + PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python" + else + PYTHON_INCLUDES="" + enable_python="no" + fi fi fi AC_SUBST(PYTHON_INCLUDES) @@ -342,6 +347,7 @@ if test x"$enable_python" = xyes; then fi fi + AC_MSG_CHECKING(Python support) AC_MSG_RESULT($enable_python) AM_CONDITIONAL(BUILD_PYTHON, test x"$enable_python" = xyes) @@ -927,4 +933,4 @@ echo "" echo "Version: $GANGLIA_VERSION" echo "Library: Release $LT_RELEASE $LT_CURRENT:$LT_REVISION:$LT_AGE" echo "" -echo "Type \"make\" to compile." +echo "Type \"make\" to compile." \ No newline at end of file diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c index ed5a4018a..da55a0df6 100644 --- a/gmond/modules/python/mod_python.c +++ b/gmond/modules/python/mod_python.c @@ -51,12 +51,23 @@ /* * Backward compatibility for 2.1 to 2.4 */ + +#if PY_MAJOR_VERSION == 2 #if PY_MINOR_VERSION < 5 #define Py_ssize_t int +#endif #if PY_MINOR_VERSION < 3 #define PyInt_AsUnsignedLongMask PyInt_AsLong #endif #endif +#if PY_MAJOR_VERSION >= 3 +#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask +#define PyInt_AsLong PyLong_AsLong +#define PyString_AsString PyThreeString_AsString +#define PyString_FromString PyThreeString_FromString +#define PyInt_Check PyLong_Check +#define PyString_Check PyThreeStringCheck +#endif /* * Declare ourselves so the configuration routines can find and know us. @@ -112,6 +123,47 @@ static char* is_python_module(const char* fname) return modname_bfr; } +static int PyThreeStringCheck(PyObject* dv) +{ + if (PyUnicode_Check(dv)) { + return 1; + } else if (PyBytes_Check(dv)) { + return 1; + } else { + return 0; + } +} + +static char* PyThreeString_AsString(PyObject* dv) +{ + if (PyUnicode_Check(dv)) { + PyObject * temp_bytes = PyUnicode_AsEncodedString(dv, "UTF-8", "strict"); // Owned reference + if (temp_bytes != NULL) { + char* result = PyBytes_AS_STRING(temp_bytes); // Borrowed pointer + result = strdup(result); + Py_DECREF(temp_bytes); + return result; + } else { + return NULL; + } + } else if (PyBytes_Check(dv)) { + char* result = PyBytes_AS_STRING(dv); // Borrowed pointer + result = strdup(result); + return result; + } else { + return NULL; + } +} + +static PyObject* PyThreeString_FromString(const char* v) +{ + PyObject* dv = PyUnicode_FromString(v); + return dv; +} + + + + int get_python_string_value(PyObject* dv, char* bfr, int len) { @@ -540,6 +592,15 @@ static PyMethodDef GangliaMethods[] = { {NULL, NULL, 0, NULL} }; +static struct PyModuleDef gangliaModPy = +{ + PyModuleDef_HEAD_INIT, + "ganglia", /* name of module */ + NULL, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ + GangliaMethods +}; + static int pyth_metric_init (apr_pool_t *p) { DIR *dp; @@ -551,6 +612,7 @@ static int pyth_metric_init (apr_pool_t *p) Ganglia_25metric *gmi; mapped_info_t *mi; const char* path = python_module.module_params; + //const char* path = "/root/cpythontest/conf/modpython.conf"; cfg_t *module_cfg; /* Allocate a pool that will be used by this module */ @@ -584,7 +646,11 @@ static int pyth_metric_init (apr_pool_t *p) /* Set up the python path to be able to load module from our module path */ Py_Initialize(); - Py_InitModule("ganglia", GangliaMethods); + #if PY_MAJOR_VERSION >= 3 + PyModule_Create(&gangliaModPy); + #else + Py_InitModule("ganglia", GangliaMethods); + #endif PyObject *sys_path = PySys_GetObject("path"); PyObject *addpath = PyString_FromString(path); @@ -836,4 +902,4 @@ mmodule python_module = NULL, NULL, /* defined dynamically */ pyth_metric_handler, -}; +}; \ No newline at end of file From d36a8b7383ab2e4c75c59eb74138f7c114261ca0 Mon Sep 17 00:00:00 2001 From: yangruochen Date: Thu, 19 Mar 2020 18:52:28 +0800 Subject: [PATCH 2/2] fix bug: PyModuleDef_HEAD_INIT undeclared --- gmond/modules/python/mod_python.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c index da55a0df6..76d86be00 100644 --- a/gmond/modules/python/mod_python.c +++ b/gmond/modules/python/mod_python.c @@ -592,6 +592,7 @@ static PyMethodDef GangliaMethods[] = { {NULL, NULL, 0, NULL} }; +#if PY_MAJOR_VERSION >= 3 static struct PyModuleDef gangliaModPy = { PyModuleDef_HEAD_INIT, @@ -600,6 +601,7 @@ static struct PyModuleDef gangliaModPy = -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ GangliaMethods }; +#endif static int pyth_metric_init (apr_pool_t *p) {