diff --git a/src/perl.c b/src/perl.c
index d0c7e372e79434a06c50cf8610de6ca158bcaee0..9eef6c1ad1c88c99798cb2b8e8857c77e42658eb 100644 (file)
--- a/src/perl.c
+++ b/src/perl.c
* collectd - src/perl.c
* Copyright (C) 2007-2009 Sebastian Harl
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; only version 2 of the License is applicable.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
- * Author:
+ * Authors:
* Sebastian Harl <sh at tokkee.org>
**/
#define DONT_POISON_SPRINTF_YET 1
#include "collectd.h"
-#undef DONT_POISON_SPRINTF_YET
-#include "configfile.h"
+#undef DONT_POISON_SPRINTF_YET
#if HAVE_STDBOOL_H
# include <stdbool.h>
#include <perl.h>
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__
+# undef sprintf
# pragma GCC poison sprintf
#endif
#include "filter_chain.h"
-#include <pthread.h>
-
#if !defined(USE_ITHREADS)
# error "Perl does not support ithreads!"
#endif /* !defined(USE_ITHREADS) */
return 0;
} /* static int hv2data_source (HV *, data_source_t *) */
-static int av2value (pTHX_ char *name, AV *array, value_t *value, int len)
+/* av2value converts at most "len" elements from "array" to "value". Returns the
+ * number of elements converted or zero on error. */
+static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len)
{
const data_set_t *ds;
- int i = 0;
-
- if ((NULL == name) || (NULL == array) || (NULL == value))
- return -1;
-
- if (av_len (array) < len - 1)
- len = av_len (array) + 1;
-
- if (0 >= len)
- return -1;
+ if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0))
+ return 0;
ds = plugin_get_ds (name);
if (NULL == ds) {
log_err ("av2value: Unknown dataset \"%s\"", name);
- return -1;
+ return 0;
}
- if (ds->ds_num < len) {
- log_warn ("av2value: Value length exceeds data set length.");
- len = ds->ds_num;
+ if (array_len < ds->ds_num) {
+ log_warn ("av2value: array does not contain enough elements for type \"%s\": got %zu, want %zu",
+ 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",
+ name, array_len, ds->ds_num);
}
- for (i = 0; i < len; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
SV **tmp = av_fetch (array, i, 0);
if (NULL != tmp) {
value[i].absolute = SvIV (*tmp);
}
else {
- return -1;
+ return 0;
}
}
- return len;
-} /* static int av2value (char *, AV *, value_t *, int) */
+
+ return ds->ds_num;
+} /* static size_t av2value (char *, AV *, value_t *, size_t) */
/*
* value list:
{
AV *array = (AV *)SvRV (*tmp);
- int len = av_len (array) + 1;
-
- if (len <= 0)
+ /* av_len returns the highest index, not the actual length. */
+ size_t array_len = (size_t) (av_len (array) + 1);
+ if (array_len == 0)
return -1;
- vl->values = (value_t *)smalloc (len * sizeof (value_t));
- vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp),
- vl->values, len);
-
- if (-1 == vl->values_len) {
+ vl->values = calloc (array_len, sizeof (*vl->values));
+ vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp), vl->values, array_len);
+ if (vl->values_len == 0) {
sfree (vl->values);
return -1;
}
static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
{
- int len, i;
+ int len;
if ((NULL == array) || (NULL == name) || (NULL == ds))
return -1;
return -1;
}
- ds->ds = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
+ ds->ds = smalloc ((len + 1) * sizeof (*ds->ds));
ds->ds_num = len + 1;
- for (i = 0; i <= len; ++i) {
+ for (int i = 0; i <= len; ++i) {
SV **elem = av_fetch (array, i, 0);
if (NULL == elem) {
notification_meta_t **m = meta;
int len = av_len (array);
- int i;
- for (i = 0; i <= len; ++i) {
+ for (int i = 0; i <= len; ++i) {
SV **tmp = av_fetch (array, i, 0);
HV *hash;
hash = (HV *)SvRV (*tmp);
- *m = (notification_meta_t *)smalloc (sizeof (**m));
+ *m = smalloc (sizeof (**m));
if (NULL == (tmp = hv_fetch (hash, "name", 4, 0))) {
log_warn ("av2notification_meta: Skipping invalid "
static int data_set2av (pTHX_ data_set_t *ds, AV *array)
{
- int i = 0;
-
if ((NULL == ds) || (NULL == array))
return -1;
av_extend (array, ds->ds_num);
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
HV *source = newHV ();
if (NULL == hv_store (source, "name", 4,
static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash)
{
AV *values = NULL;
-
- int i = 0;
- int len = 0;
+ size_t i;
if ((NULL == vl) || (NULL == ds) || (NULL == hash))
return -1;
- len = vl->values_len;
-
- if (ds->ds_num < len) {
- log_warn ("value2av: Value length exceeds data set length.");
- len = ds->ds_num;
- }
-
values = newAV ();
- av_extend (values, len - 1);
+ /* av_extend takes the last *index* to which the array should be extended. */
+ av_extend (values, vl->values_len - 1);
- for (i = 0; i < len; ++i) {
+ assert (ds->ds_num == vl->values_len);
+ for (i = 0; i < vl->values_len; ++i) {
SV *val = NULL;
if (DS_TYPE_COUNTER == ds->ds[i].type)
static int notification_meta2av (pTHX_ notification_meta_t *meta, AV *array)
{
int meta_num = 0;
- int i;
while (meta) {
++meta_num;
av_extend (array, meta_num);
- for (i = 0; NULL != meta; meta = meta->next, ++i) {
+ for (int i = 0; NULL != meta; meta = meta->next, ++i) {
HV *m = newHV ();
SV *value;
static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash)
{
- int i;
-
AV *values;
AV *children;
return -1;
}
- for (i = 0; i < ci->values_num; ++i) {
+ for (int i = 0; i < ci->values_num; ++i) {
SV *value;
switch (ci->values[i].type) {
return -1;
}
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
HV *child = newHV ();
if (0 != oconfig_item2hv (aTHX_ ci->children + i, child)) {
*/
static int pplugin_dispatch_notification (pTHX_ HV *notif)
{
- notification_t n;
+ notification_t n = { 0 };
int ret;
if (NULL == notif)
return -1;
- memset (&n, 0, sizeof (n));
-
if (0 != hv2notification (aTHX_ notif, &n))
return -1;
assert (NULL != perl_threads);
- t = (c_ithread_t *)smalloc (sizeof (c_ithread_t));
+ t = smalloc (sizeof (*t));
memset (t, 0, sizeof (c_ithread_t));
t->interp = (NULL == base)
return -1;
}
- data = (pfc_user_data_t *)smalloc (sizeof (*data));
+ data = smalloc (sizeof (*data));
data->name = sstrdup (ci->values[0].value.string);
data->user_data = newSV (0);
static int perl_shutdown (void)
{
- c_ithread_t *t = NULL;
-
- int ret = 0;
+ c_ithread_t *t;
+ int ret;
dTHX;
return 0;
if (NULL == aTHX) {
- t = NULL;
-
pthread_mutex_lock (&perl_threads->mutex);
t = c_ithread_create (perl_threads->head->interp);
pthread_mutex_unlock (&perl_threads->mutex);
SV *tmp = NULL;
char *file = __FILE__;
- int i = 0;
-
dXSUB_SYS;
/* enable usage of Perl modules using shared libraries */
newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
/* register API */
- for (i = 0; NULL != api[i].f; ++i)
+ for (int i = 0; NULL != api[i].f; ++i)
newXS (api[i].name, api[i].f, file);
stash = gv_stashpv ("Collectd", 1);
/* export "constants" */
- for (i = 0; '\0' != constants[i].name[0]; ++i)
+ for (int i = 0; '\0' != constants[i].name[0]; ++i)
newCONSTSUB (stash, constants[i].name, newSViv (constants[i].value));
/* export global variables
* accessing any such variable (this is basically the same as using
* tie() in Perl) */
/* global strings */
- for (i = 0; '\0' != g_strings[i].name[0]; ++i) {
+ 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);
log_info ("Initializing Perl interpreter...");
#if COLLECT_DEBUG
{
- int i = 0;
-
- for (i = 0; i < argc; ++i)
+ for (int i = 0; i < argc; ++i)
log_debug ("argv[%i] = \"%s\"", i, argv[i]);
}
#endif /* COLLECT_DEBUG */
#endif
PERL_SYS_INIT3 (&argc, &argv, &environ);
- perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
+ perl_threads = smalloc (sizeof (*perl_threads));
memset (perl_threads, 0, sizeof (c_ithread_list_t));
pthread_mutexattr_init(&perl_threads->mutexattr);
value = ci->values[0].value.string;
- perl_argv = (char **)realloc (perl_argv,
+ perl_argv = realloc (perl_argv,
(++perl_argc + 1) * sizeof (char *));
if (NULL == perl_argv) {
perl_argv[perl_argc - 1] = "-d";
}
else {
- perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 4);
+ perl_argv[perl_argc - 1] = smalloc (strlen (value) + 4);
sstrncpy (perl_argv[perl_argc - 1], "-d:", 4);
sstrncpy (perl_argv[perl_argc - 1] + 3, value, strlen (value) + 1);
}
value = ci->values[0].value.string;
if (NULL == aTHX) {
- perl_argv = (char **)realloc (perl_argv,
+ perl_argv = realloc (perl_argv,
(++perl_argc + 1) * sizeof (char *));
if (NULL == perl_argv) {
exit (3);
}
- perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 3);
+ perl_argv[perl_argc - 1] = smalloc (strlen (value) + 3);
sstrncpy(perl_argv[perl_argc - 1], "-I", 3);
sstrncpy(perl_argv[perl_argc - 1] + 2, value, strlen (value) + 1);
static int perl_config (oconfig_item_t *ci)
{
int status = 0;
- int i = 0;
dTHXa (NULL);
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
int current_status = 0;
void module_register (void)
{
perl_argc = 4;
- perl_argv = (char **)smalloc ((perl_argc + 1) * sizeof (char *));
+ perl_argv = smalloc ((perl_argc + 1) * sizeof (*perl_argv));
/* default options for the Perl interpreter */
perl_argv[0] = "";