#undef DONT_POISON_SPRINTF_YET
-#if HAVE_STDBOOL_H
#include <stdbool.h>
-#endif
#include <EXTERN.h>
#include <perl.h>
typedef struct c_ithread_s {
/* the thread's Perl interpreter */
PerlInterpreter *interp;
- _Bool running; /* thread is inside Perl interpreter */
- _Bool shutdown;
+ bool running; /* thread is inside Perl interpreter */
+ bool shutdown;
pthread_t pthread;
/* double linked list of threads */
* private variables
*/
-static _Bool register_legacy_flush = 1;
+static bool register_legacy_flush = true;
/* if perl_threads != NULL perl_threads->head must
* point to the "base" thread */
-static c_ithread_list_t *perl_threads = NULL;
+static c_ithread_list_t *perl_threads;
/* the key used to store each pthread's ithread */
static pthread_key_t perl_thr_key;
-static int perl_argc = 0;
-static char **perl_argv = NULL;
+static int perl_argc;
+static char **perl_argv;
static char base_name[DATA_MAX_NAME_LEN] = "";
{"Collectd::NOTIF_WARNING", NOTIF_WARNING},
{"Collectd::NOTIF_OKAY", NOTIF_OKAY},
{"", 0}};
-
-struct {
- char name[64];
- char *var;
-} g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
-
/*
* Helper functions for data type conversion.
*/
if (array_len < ds->ds_num) {
log_warn("av2value: array does not contain enough elements for type "
- "\"%s\": got %zu, want %zu",
+ "\"%s\": got %" PRIsz ", want %" PRIsz,
name, array_len, ds->ds_num);
return 0;
} else if (array_len > ds->ds_num) {
log_warn("av2value: array contains excess elements for type \"%s\": got "
- "%zu, want %zu",
+ "%" PRIsz ", want %" PRIsz,
name, array_len, ds->ds_num);
}
if (NULL != (tmp = hv_fetch(hash, "host", 4, 0)))
sstrncpy(vl->host, SvPV_nolen(*tmp), sizeof(vl->host));
- else
- sstrncpy(vl->host, hostname_g, sizeof(vl->host));
if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0)))
sstrncpy(vl->plugin, SvPV_nolen(*tmp), sizeof(vl->plugin));
* meta => [ { name => <name>, value => <value> }, ... ]
* }
*/
-static int av2notification_meta(pTHX_ AV *array, notification_meta_t **meta) {
- notification_meta_t **m = meta;
+static int av2notification_meta(pTHX_ AV *array,
+ notification_meta_t **ret_meta) {
+ notification_meta_t *tail = NULL;
int len = av_len(array);
for (int i = 0; i <= len; ++i) {
SV **tmp = av_fetch(array, i, 0);
- HV *hash;
- if (NULL == tmp)
+ if (tmp == NULL)
return -1;
if (!(SvROK(*tmp) && (SVt_PVHV == SvTYPE(SvRV(*tmp))))) {
continue;
}
- hash = (HV *)SvRV(*tmp);
+ HV *hash = (HV *)SvRV(*tmp);
- *m = smalloc(sizeof(**m));
+ notification_meta_t *m = calloc(1, sizeof(*m));
+ if (m == NULL)
+ return ENOMEM;
- if (NULL == (tmp = hv_fetch(hash, "name", 4, 0))) {
+ SV **name = hv_fetch(hash, "name", strlen("name"), 0);
+ if (name == NULL) {
log_warn("av2notification_meta: Skipping invalid "
"meta information.");
- free(*m);
+ sfree(m);
continue;
}
- sstrncpy((*m)->name, SvPV_nolen(*tmp), sizeof((*m)->name));
+ sstrncpy(m->name, SvPV_nolen(*name), sizeof(m->name));
- if (NULL == (tmp = hv_fetch(hash, "value", 5, 0))) {
+ SV **value = hv_fetch(hash, "value", strlen("value"), 0);
+ if (value == NULL) {
log_warn("av2notification_meta: Skipping invalid "
"meta information.");
- free(*m);
+ sfree(m);
continue;
}
- if (SvNOK(*tmp)) {
- (*m)->nm_value.nm_double = SvNVX(*tmp);
- (*m)->type = NM_TYPE_DOUBLE;
- } else if (SvUOK(*tmp)) {
- (*m)->nm_value.nm_unsigned_int = SvUVX(*tmp);
- (*m)->type = NM_TYPE_UNSIGNED_INT;
- } else if (SvIOK(*tmp)) {
- (*m)->nm_value.nm_signed_int = SvIVX(*tmp);
- (*m)->type = NM_TYPE_SIGNED_INT;
+ if (SvNOK(*value)) {
+ m->nm_value.nm_double = SvNVX(*value);
+ m->type = NM_TYPE_DOUBLE;
+ } else if (SvUOK(*value)) {
+ m->nm_value.nm_unsigned_int = SvUVX(*value);
+ m->type = NM_TYPE_UNSIGNED_INT;
+ } else if (SvIOK(*value)) {
+ m->nm_value.nm_signed_int = SvIVX(*value);
+ m->type = NM_TYPE_SIGNED_INT;
} else {
- (*m)->nm_value.nm_string = sstrdup(SvPV_nolen(*tmp));
- (*m)->type = NM_TYPE_STRING;
+ m->nm_value.nm_string = sstrdup(SvPV_nolen(*value));
+ m->type = NM_TYPE_STRING;
}
- (*m)->next = NULL;
- m = &((*m)->next);
+ m->next = NULL;
+ if (tail == NULL)
+ *ret_meta = m;
+ else
+ tail->next = m;
+ tail = m;
}
+
return 0;
} /* static int av2notification_meta (AV *, notification_meta_t *) */
static int notification_meta2av(pTHX_ notification_meta_t *meta, AV *array) {
int meta_num = 0;
-
- while (meta) {
+ for (notification_meta_t *m = meta; m != NULL; m = m->next) {
++meta_num;
- meta = meta->next;
}
av_extend(array, meta_num);
static char *get_module_name(char *buf, size_t buf_len, const char *module) {
int status = 0;
if (base_name[0] == '\0')
- status = ssnprintf(buf, buf_len, "%s", module);
+ status = snprintf(buf, buf_len, "%s", module);
else
- status = ssnprintf(buf, buf_len, "%s::%s", base_name, module);
+ status = snprintf(buf, buf_len, "%s::%s", base_name, module);
if ((status < 0) || ((unsigned int)status >= buf_len))
- return (NULL);
- return (buf);
+ return NULL;
+ return buf;
} /* char *get_module_name */
/*
* Call perl sub with thread locking flags handled.
*/
static int call_pv_locked(pTHX_ const char *sub_name) {
- _Bool old_running;
+ bool old_running;
int ret;
c_ithread_t *t = (c_ithread_t *)pthread_getspecific(perl_thr_key);
return 0;
old_running = t->running;
- t->running = 1;
+ t->running = true;
if (t->shutdown) {
t->running = old_running;
/* Mark as running to avoid deadlock:
c_ithread_destroy -> log_debug -> perl_log()
*/
- ithread->running = 1;
+ ithread->running = true;
log_debug("Shutting down Perl interpreter %p...", aTHX);
#if COLLECT_DEBUG
}
t->pthread = pthread_self();
- t->running = 0;
- t->shutdown = 0;
+ t->running = false;
+ t->shutdown = false;
perl_threads->tail = t;
pthread_setspecific(perl_thr_key, (const void *)t);
ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
}
- if (0 == ret)
+ if (0 == ret) {
ret = plugin_register_flush(pluginname, perl_flush, &userdata);
+ } else {
+ free(userdata.data);
+ }
} else {
ret = -1;
}
if (0 == ret)
XSRETURN_YES;
- else {
- free(userdata.data);
+ else
XSRETURN_EMPTY;
- }
} /* static void _plugin_register_generic_userdata ( ... ) */
/*
/* Lock the base thread to avoid race conditions with c_ithread_create().
* See https://github.com/collectd/collectd/issues/9 and
* https://github.com/collectd/collectd/issues/1706 for details.
- */
+ */
assert(aTHX == perl_threads->head->interp);
pthread_mutex_lock(&perl_threads->mutex);
/* Lock the base thread if this is not called from one of the read threads
* to avoid race conditions with c_ithread_create(). See
* https://github.com/collectd/collectd/issues/9 for details.
- */
+ */
if (aTHX == perl_threads->head->interp)
pthread_mutex_lock(&perl_threads->mutex);
* the thread as this will free the memory */
t = t->prev;
- thr->shutdown = 1;
+ thr->shutdown = true;
if (thr->running) {
/* Give some time to thread to exit from Perl interpreter */
WARNING("perl shutdown: Thread is running inside Perl. Waiting.");
return 0;
} /* static int g_interval_set (pTHX_ SV *, MAGIC *) */
-static MGVTBL g_pv_vtbl = {g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL
+static MGVTBL g_pv_vtbl = {g_pv_get,
+ g_pv_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
#if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
,
NULL
#endif
};
-static MGVTBL g_interval_vtbl = {g_interval_get, g_interval_set, NULL, NULL,
- NULL, NULL, NULL
+static MGVTBL g_interval_vtbl = {g_interval_get,
+ g_interval_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
#if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
,
NULL
* accessing any such variable (this is basically the same as using
* tie() in Perl) */
/* global strings */
+ struct {
+ char name[64];
+ char *var;
+ } g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
+
for (int i = 0; '\0' != g_strings[i].name[0]; ++i) {
tmp = get_sv(g_strings[i].name, 1);
sv_magicext(tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl, g_strings[i].var, 0);
if (NULL == get_module_name(module_name, sizeof(module_name), value)) {
log_err("Invalid module name %s", value);
- return (1);
+ return 1;
}
if (0 != init_pi(perl_argc, perl_argv))
char *plugin;
HV *config;
+ if (NULL == perl_threads) {
+ log_err("A `Plugin' block was encountered but no plugin was loaded yet. "
+ "Put the appropriate `LoadPlugin' option in front of it.");
+ return -1;
+ }
+
dSP;
if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) {