--- /dev/null
+=pod
+
+=head1 NAME
+
+librrd - RRD library functions
+
+=head1 DESCRIPTION
+
+B<librrd> contains most of the functionality in B<RRDTool>. The command
+line utilities and language bindings are often just wrappers around the
+code contained in B<librrd>.
+
+This manual page documents the B<librrd> API.
+
+B<NOTE:> This document is a work in progress, and should be considered
+incomplete as long as this warning persists. For more information about
+the B<librrd> functions, always consult the source code.
+
+=head1 UTILITY FUNCTIONS
+
+=over
+
+=item B<rrd_random()>
+
+Generates random numbers just like random(). This further ensures that
+the random number generator is seeded exactly once per process.
+
+=item B<rrd_add_ptr(void ***dest, size_t *dest_size, void *src)>
+
+Dynamically resize the array pointed to by C<dest>. C<dest_size> is a
+pointer to the current size of C<dest>. Upon successful realloc(), the
+C<dest_size> is incremented by 1 and the C<src> pointer is stored at the
+end of the new C<dest>. Returns 1 on success, 0 on failure.
+
+ type **arr = NULL;
+ type *elem = "whatever";
+ size_t arr_size = 0;
+ if (!rrd_add_ptr(&arr, &arr_size, elem))
+ handle_failure();
+
+=item B<rrd_add_strdup(char ***dest, size_t *dest_size, char *src)>
+
+Like C<rrd_add_ptr>, except adds a C<strdup> of the source string.
+
+ char **arr = NULL;
+ size_t arr_size = NULL;
+ char *str = "example text";
+ if (!rrd_add_strdup(&arr, &arr_size, str))
+ handle_failure();
+
+=item B<rrd_free_ptrs(void ***src, size_t *cnt)>
+
+Free an array of pointers allocated by C<rrd_add_ptr> or
+C<rrd_add_strdup>. Also frees the array pointer itself. On return, the
+source pointer will be NULL and the count will be zero.
+
+ /* created as above */
+ rrd_free_ptrs(&arr, &arr_size);
+ /* here, arr == NULL && arr_size == 0 */
+
+=back
{
char *file;
char **values;
- int values_num;
+ size_t values_num;
time_t last_flush_time;
time_t last_update_stamp;
#define CI_FLAGS_IN_TREE (1<<0)
static int config_write_base_only = 0;
static listen_socket_t **config_listen_address_list = NULL;
-static int config_listen_address_list_len = 0;
+static size_t config_listen_address_list_len = 0;
static uint64_t stats_queue_length = 0;
static uint64_t stats_updates_received = 0;
remove_from_queue(ci);
- for (int i=0; i < ci->values_num; i++)
+ for (size_t i=0; i < ci->values_num; i++)
free(ci->values[i]);
free (ci->values);
else if (((cfd->now - ci->last_flush_time) >= config_flush_interval)
&& (ci->values_num <= 0))
{
- char **temp;
-
- temp = (char **) rrd_realloc (cfd->keys,
- sizeof (char *) * (cfd->keys_num + 1));
- if (temp == NULL)
+ assert ((char *) key == ci->file);
+ if (!rrd_add_ptr((void ***)&cfd->keys, &cfd->keys_num, (void *)key))
{
- RRDD_LOG (LOG_ERR, "tree_callback_flush: realloc failed.");
+ RRDD_LOG (LOG_ERR, "tree_callback_flush: rrd_add_ptrs failed.");
return (FALSE);
}
- cfd->keys = temp;
- /* Make really sure this points to the _same_ place */
- assert ((char *) key == ci->file);
- cfd->keys[cfd->keys_num] = (char *) key;
- cfd->keys_num++;
}
return (FALSE);
cache_item_t *ci;
char *file;
char **values;
- int values_num;
+ size_t values_num;
int status;
- int i;
/* Now, check if there's something to store away. If not, wait until
* something comes in. if we are shutting down, do not wait around. */
pthread_mutex_unlock (&cache_lock);
rrd_clear_error ();
- status = rrd_update_r (file, NULL, values_num, (void *) values);
+ status = rrd_update_r (file, NULL, (int) values_num, (void *) values);
if (status != 0)
{
RRDD_LOG (LOG_NOTICE, "queue_thread_main: "
journal_write("wrote", file);
pthread_cond_broadcast(&ci->flushed);
- for (i = 0; i < values_num; i++)
- free (values[i]);
-
- free(values);
+ rrd_free_ptrs((void ***) &values, &values_num);
free(file);
if (status == 0)
return send_response(sock, RESP_ERR, "%s\n", rrd_strerror(ENOENT));
}
- for (int i=0; i < ci->values_num; i++)
+ for (size_t i=0; i < ci->values_num; i++)
add_response_info(sock, "%s\n", ci->values[i]);
pthread_mutex_unlock(&cache_lock);
while (buffer_size > 0)
{
- char **temp;
char *value;
time_t stamp;
char *eostamp;
else
ci->last_update_stamp = stamp;
- temp = (char **) rrd_realloc (ci->values,
- sizeof (char *) * (ci->values_num + 1));
- if (temp == NULL)
- {
- RRDD_LOG (LOG_ERR, "handle_request_update: realloc failed.");
- continue;
- }
- ci->values = temp;
-
- ci->values[ci->values_num] = strdup (value);
- if (ci->values[ci->values_num] == NULL)
+ if (!rrd_add_strdup(&ci->values, &ci->values_num, value))
{
- RRDD_LOG (LOG_ERR, "handle_request_update: strdup failed.");
+ RRDD_LOG (LOG_ERR, "handle_request_update: rrd_add_strdup failed.");
continue;
}
- ci->values_num++;
values_num++;
}
*/
static int handle_request_wrote (HANDLER_PROTO) /* {{{ */
{
- int i;
cache_item_t *ci;
const char *file = buffer;
}
if (ci->values)
- {
- for (i=0; i < ci->values_num; i++)
- free(ci->values[i]);
-
- free(ci->values);
- }
+ rrd_free_ptrs((void ***) &ci->values, &ci->values_num);
wipe_ci_values(ci, now);
remove_from_queue(ci);
/* open all the listen sockets */
if (config_listen_address_list_len > 0)
{
- for (int i = 0; i < config_listen_address_list_len; i++)
- {
+ for (size_t i = 0; i < config_listen_address_list_len; i++)
open_listen_socket (config_listen_address_list[i]);
- free_listen_socket (config_listen_address_list[i]);
- }
- free(config_listen_address_list);
+ rrd_free_ptrs((void ***) &config_listen_address_list,
+ &config_listen_address_list_len);
}
else
{
case 'L':
case 'l':
{
- listen_socket_t **temp;
listen_socket_t *new;
new = malloc(sizeof(listen_socket_t));
}
memset(new, 0, sizeof(listen_socket_t));
- temp = (listen_socket_t **) rrd_realloc (config_listen_address_list,
- sizeof (listen_socket_t *) * (config_listen_address_list_len + 1));
- if (temp == NULL)
- {
- fprintf (stderr, "read_options: realloc failed.\n");
- return (2);
- }
- config_listen_address_list = temp;
-
strncpy(new->addr, optarg, sizeof(new->addr)-1);
new->privilege = (option == 'l') ? PRIV_HIGH : PRIV_LOW;
- temp[config_listen_address_list_len] = new;
- config_listen_address_list_len++;
+ if (!rrd_add_ptr((void ***)&config_listen_address_list,
+ &config_listen_address_list_len, new))
+ {
+ fprintf(stderr, "read_options: rrd_add_ptr failed.\n");
+ return (2);
+ }
}
break;