summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 1ac2983)
raw | patch | inline | side by side (parent: 1ac2983)
author | Florian octo Forster <octo@dev4.office.noris.de> | |
Wed, 27 Feb 2008 09:22:19 +0000 (10:22 +0100) | ||
committer | Florian octo Forster <octo@dev4.office.noris.de> | |
Wed, 27 Feb 2008 09:22:19 +0000 (10:22 +0100) |
SPARC and possibly other architectures cannot access arbitrary memory
locations. This caused a `bus error' on SPARC when the network plugin was
loaded. This change hopefully fixes this problem.
locations. This caused a `bus error' on SPARC when the network plugin was
loaded. This change hopefully fixes this problem.
src/network.c | patch | blob | history |
diff --git a/src/network.c b/src/network.c
index 17038a45a0a9e09416b0ce5d28f43bafd005469e..469baf7b8bbd7436ab591052a4206a55d3cbe7c4 100644 (file)
--- a/src/network.c
+++ b/src/network.c
static int write_part_values (char **ret_buffer, int *ret_buffer_len,
const data_set_t *ds, const value_list_t *vl)
{
- part_values_t pv;
+ char *packet_ptr;
+ int packet_len;
+ int num_values;
+
+ part_header_t pkg_ph;
+ uint16_t pkg_num_values;
+ uint8_t *pkg_values_types;
+ value_t *pkg_values;
+
+ int offset;
int i;
- i = 6 + (9 * vl->values_len);
- if (*ret_buffer_len < i)
+ num_values = vl->values_len;
+ packet_len = sizeof (part_header_t) + sizeof (uint16_t)
+ + (num_values * sizeof (uint8_t))
+ + (num_values * sizeof (value_t));
+
+ if (*ret_buffer_len < packet_len)
return (-1);
- *ret_buffer_len -= i;
- pv.head = (part_header_t *) *ret_buffer;
- pv.num_values = (uint16_t *) (pv.head + 1);
- pv.values_types = (uint8_t *) (pv.num_values + 1);
- pv.values = (value_t *) (pv.values_types + vl->values_len);
- *ret_buffer = (void *) (pv.values + vl->values_len);
+ pkg_values_types = (uint8_t *) malloc (num_values * sizeof (uint8_t));
+ if (pkg_values_types == NULL)
+ {
+ ERROR ("network plugin: write_part_values: malloc failed.");
+ return (-1);
+ }
- pv.head->type = htons (TYPE_VALUES);
- pv.head->length = htons (6 + (9 * vl->values_len));
- *pv.num_values = htons ((uint16_t) vl->values_len);
-
- for (i = 0; i < vl->values_len; i++)
+ pkg_values = (value_t *) malloc (num_values * sizeof (value_t));
+ if (pkg_values == NULL)
+ {
+ free (pkg_values_types);
+ ERROR ("network plugin: write_part_values: malloc failed.");
+ return (-1);
+ }
+
+ pkg_ph.type = htons (TYPE_VALUES);
+ pkg_ph.length = htons (packet_len);
+
+ pkg_num_values = htons ((uint16_t) vl->values_len);
+
+ for (i = 0; i < num_values; i++)
{
if (ds->ds[i].type == DS_TYPE_COUNTER)
{
- pv.values_types[i] = DS_TYPE_COUNTER;
- pv.values[i].counter = htonll (vl->values[i].counter);
+ pkg_values_types[i] = DS_TYPE_COUNTER;
+ pkg_values[i].counter = htonll (vl->values[i].counter);
}
else
{
- pv.values_types[i] = DS_TYPE_GAUGE;
- pv.values[i].gauge = vl->values[i].gauge;
+ pkg_values_types[i] = DS_TYPE_GAUGE;
+ pkg_values[i].gauge = vl->values[i].gauge;
}
- } /* for (values) */
+ }
+
+ /*
+ * Use `memcpy' to write everything to the buffer, because the pointer
+ * may be unaligned and some architectures, such as SPARC, can't handle
+ * that.
+ */
+ packet_ptr = *ret_buffer;
+ offset = 0;
+ memcpy (packet_ptr + offset, &pkg_ph, sizeof (pkg_ph));
+ offset += sizeof (pkg_ph);
+ memcpy (packet_ptr + offset, &pkg_num_values, sizeof (pkg_num_values));
+ offset += sizeof (pkg_num_values);
+ memcpy (packet_ptr + offset, pkg_values_types, num_values * sizeof (uint8_t));
+ offset += num_values * sizeof (uint8_t);
+ memcpy (packet_ptr + offset, pkg_values, num_values * sizeof (value_t));
+ offset += num_values * sizeof (value_t);
+
+ assert (offset == packet_len);
+
+ *ret_buffer = packet_ptr + packet_len;
+ *ret_buffer_len -= packet_len;
+
+ free (pkg_values_types);
+ free (pkg_values);
return (0);
} /* int write_part_values */
static int write_part_number (char **ret_buffer, int *ret_buffer_len,
int type, uint64_t value)
{
- part_number_t pn;
+ char *packet_ptr;
+ int packet_len;
+
+ part_header_t pkg_head;
+ uint64_t pkg_value;
+
+ int offset;
+
+ packet_len = sizeof (pkg_head) + sizeof (pkg_value);
- if (*ret_buffer_len < 12)
+ if (*ret_buffer_len < packet_len)
return (-1);
- pn.head = (part_header_t *) *ret_buffer;
- pn.value = (uint64_t *) (pn.head + 1);
+ pkg_head.type = htons (type);
+ pkg_head.length = htons (packet_len);
+ pkg_value = htonll (value);
- pn.head->type = htons (type);
- pn.head->length = htons (12);
- *pn.value = htonll (value);
+ packet_ptr = *ret_buffer;
+ offset = 0;
+ memcpy (packet_ptr + offset, &pkg_head, sizeof (pkg_head));
+ offset += sizeof (pkg_head);
+ memcpy (packet_ptr + offset, &pkg_value, sizeof (pkg_value));
+ offset += sizeof (pkg_value);
- *ret_buffer = (char *) (pn.value + 1);
- *ret_buffer_len -= 12;
+ assert (offset == packet_len);
+
+ *ret_buffer = packet_ptr + packet_len;
+ *ret_buffer_len -= packet_len;
return (0);
} /* int write_part_number */
static int write_part_string (char **ret_buffer, int *ret_buffer_len,
int type, const char *str, int str_len)
{
- part_string_t ps;
- int len;
+ char *packet_ptr;
+ int packet_len;
+
+ part_header_t pkg_head;
+
+ int offset;
- len = 4 + str_len + 1;
- if (*ret_buffer_len < len)
+ packet_len = sizeof (pkg_head) + str_len + 1;
+ if (*ret_buffer_len < packet_len)
return (-1);
- *ret_buffer_len -= len;
- ps.head = (part_header_t *) *ret_buffer;
- ps.value = (char *) (ps.head + 1);
+ pkg_head.type = htons (type);
+ pkg_head.length = htons (packet_len);
+
+ packet_ptr = *ret_buffer;
+ offset = 0;
+ memcpy (packet_ptr + offset, &pkg_head, sizeof (pkg_head));
+ offset += sizeof (pkg_head);
+ memcpy (packet_ptr + offset, str, str_len);
+ offset += str_len;
+ memset (packet_ptr + offset, '\0', 1);
+ offset += 1;
+
+ assert (offset == packet_len);
- ps.head->type = htons ((uint16_t) type);
- ps.head->length = htons ((uint16_t) str_len + 5);
- if (str_len > 0)
- memcpy (ps.value, str, str_len);
- ps.value[str_len] = '\0';
- *ret_buffer = (void *) (ps.value + (str_len + 1));
+ *ret_buffer = packet_ptr + packet_len;
+ *ret_buffer_len -= packet_len;
return (0);
} /* int write_part_string */