* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Sven Trenkel <collectd at semidefinite.de>
+ * Sven Trenkel <collectd at semidefinite.de>
**/
#include <Python.h>
#include <structmember.h>
#include <signal.h>
-#if HAVE_PTHREAD_H
-# include <pthread.h>
-#endif
#include "collectd.h"
+
#include "common.h"
#include "cpython.h"
static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) {
const char *module = NULL;
PyObject *mod = NULL;
-
+
if (name != NULL) {
snprintf(buf, size, "python.%s", name);
return;
}
-
+
mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
if (mod != NULL)
module = cpy_unicode_or_bytes_to_string(&mod);
-
+
if (module != NULL) {
snprintf(buf, size, "python.%s", module);
Py_XDECREF(mod);
return;
}
Py_XDECREF(mod);
-
+
snprintf(buf, size, "python.%p", callback);
PyErr_Clear();
}
void cpy_log_exception(const char *context) {
- int l = 0, i;
+ int l = 0;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
-
+
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
if (type == NULL) return;
if (list)
l = PyObject_Length(list);
- for (i = 0; i < l; ++i) {
+ for (int i = 0; i < l; ++i) {
PyObject *line;
char const *msg;
char *cpy;
}
static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
- size_t i;
cpy_callback_t *c = data->data;
PyObject *ret, *list, *temp, *dict = NULL;
Values *v;
cpy_log_exception("write callback");
CPY_RETURN_FROM_THREADS 0;
}
- for (i = 0; i < value_list->values_len; ++i) {
+ for (size_t i = 0; i < value_list->values_len; ++i) {
if (ds->ds[i].type == DS_TYPE_COUNTER) {
PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
meta_data_t *meta = value_list->meta;
num = meta_data_toc(meta, &table);
- for (i = 0; i < num; ++i) {
+ for (size_t i = 0; i < num; ++i) {
int type;
char *string;
int64_t si;
uint64_t ui;
double d;
_Bool b;
-
+
type = meta_data_type(meta, table[i]);
if (type == MD_TYPE_STRING) {
if (meta_data_get_string(meta, table[i], &string))
char *name = NULL;
PyObject *callback = NULL, *data = NULL, *mod = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
}
static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
- size_t i;
char *name;
const data_set_t *ds;
PyObject *list, *tuple;
return NULL;
}
list = PyList_New(ds->ds_num); /* New reference. */
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
tuple = PyTuple_New(4);
PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name));
PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
int timeout = -1;
char *plugin = NULL, *identifier = NULL;
static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL;
Py_BEGIN_ALLOW_THREADS
plugin_flush(plugin, timeout, identifier);
char buf[512];
reg_function_t *register_function = (reg_function_t *) reg;
cpy_callback_t *c = NULL;
- user_data_t user_data;
+ user_data_t user_data = { 0 };
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
}
cpy_build_name(buf, sizeof(buf), callback, name);
PyMem_Free(name);
-
+
Py_INCREF(callback);
Py_XINCREF(data);
c->data = data;
c->next = NULL;
- memset (&user_data, 0, sizeof (user_data));
user_data.free_func = cpy_destroy_user_data;
user_data.data = c;
static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
char buf[512];
cpy_callback_t *c = NULL;
- user_data_t user_data;
+ user_data_t user_data = { 0 };
double interval = 0;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
}
cpy_build_name(buf, sizeof(buf), callback, name);
PyMem_Free(name);
-
+
Py_INCREF(callback);
Py_XINCREF(data);
c->data = data;
c->next = NULL;
- memset (&user_data, 0, sizeof (user_data));
user_data.free_func = cpy_destroy_user_data;
user_data.data = c;
};
static int cpy_shutdown(void) {
- cpy_callback_t *c;
PyObject *ret;
-
+
/* This can happen if the module was loaded but not configured. */
if (state != NULL)
PyEval_RestoreThread(state);
- for (c = cpy_shutdown_callbacks; c; c = c->next) {
+ for (cpy_callback_t *c = cpy_shutdown_callbacks; c; c = c->next) {
ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
if (ret == NULL)
cpy_log_exception("shutdown callback");
static void *cpy_interactive(void *data) {
sigset_t sigset;
- struct sigaction sig_int_action, old;
-
+ struct sigaction old;
+
/* Signal handler in a plugin? Bad stuff, but the best way to
* handle it I guess. In an interactive session people will
* press Ctrl+C at some time, which will generate a SIGINT.
* This will cause collectd to shutdown, thus killing the
* interactive interpreter, and leaving the terminal in a
* mess. Chances are, this isn't what the user wanted to do.
- *
+ *
* So this is the plan:
* 1. Block SIGINT in the main thread.
* 2. Install our own signal handler that does nothing.
* still interrupt syscalls like sleep and pause.
* It does not raise a KeyboardInterrupt exception because so
* far nobody managed to figure out how to do that. */
- memset (&sig_int_action, '\0', sizeof (sig_int_action));
- sig_int_action.sa_handler = cpy_int_handler;
+ struct sigaction sig_int_action = {
+ .sa_handler = cpy_int_handler
+ };
sigaction (SIGINT, &sig_int_action, &old);
-
+
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
}
static int cpy_init(void) {
- cpy_callback_t *c;
PyObject *ret;
static pthread_t thread;
sigset_t sigset;
-
+
if (!Py_IsInitialized()) {
WARNING("python: Plugin loaded but not configured.");
plugin_unregister_shutdown("python");
}
PyEval_InitThreads();
/* Now it's finally OK to use python threads. */
- for (c = cpy_init_callbacks; c; c = c->next) {
+ for (cpy_callback_t *c = cpy_init_callbacks; c; c = c->next) {
ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
if (ret == NULL)
cpy_log_exception("init callback");
}
static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
- int i;
PyObject *item, *values, *children, *tmp;
-
+
if (parent == NULL)
parent = Py_None;
-
+
values = PyTuple_New(ci->values_num); /* New reference. */
- for (i = 0; i < ci->values_num; ++i) {
+ for (int i = 0; i < ci->values_num; ++i) {
if (ci->values[i].type == OCONFIG_TYPE_STRING) {
PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
} else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean));
}
}
-
+
tmp = cpy_string_to_unicode_or_bytes(ci->key);
item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None);
if (item == NULL)
return NULL;
children = PyTuple_New(ci->children_num); /* New reference. */
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item));
}
tmp = ((Config *) item)->children;
#else
char *argv = "";
#endif
-
+
Py_Initialize();
-
+
PyType_Ready(&ConfigType);
PyType_Ready(&PluginDataType);
ValuesType.tp_base = &PluginDataType;
}
static int cpy_config(oconfig_item_t *ci) {
- int i;
PyObject *tb;
/* Ok in theory we shouldn't do initialization at this point
if (!Py_IsInitialized() && cpy_init_python()) return 1;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
if (strcasecmp(item->key, "Interactive") == 0) {
if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
continue;
} else if (strcasecmp(item->key, "ModulePath") == 0) {
char *dir = NULL;
PyObject *dir_object;
-
- if (cf_util_get_string(item, &dir) != 0)
+
+ if (cf_util_get_string(item, &dir) != 0)
continue;
dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
if (dir_object == NULL) {
} else if (strcasecmp(item->key, "Import") == 0) {
char *module_name = NULL;
PyObject *module;
-
- if (cf_util_get_string(item, &module_name) != 0)
+
+ if (cf_util_get_string(item, &module_name) != 0)
continue;
module = PyImport_ImportModule(module_name); /* New reference. */
if (module == NULL) {
char *name = NULL;
cpy_callback_t *c;
PyObject *ret;
-
+
if (cf_util_get_string(item, &name) != 0)
continue;
for (c = cpy_config_callbacks; c; c = c->next) {