int r;
// Make the path
- r = snprintf(path, sizeof(path), "/proc/pressure/%s", what);
+ r = collecty_string_format(path, "/proc/pressure/%s", what);
if (r < 0)
return -errno;
}
// Store the key
- r = snprintf(key, sizeof(key), "%s", t);
+ r = collecty_string_set(key, t);
if (r < 0) {
r = -errno;
goto ERROR;
return -errno;
// Store proto
- r = snprintf(o->proto, sizeof(o->proto), "%s", proto);
+ r = collecty_string_set(o->proto, proto);
if (r < 0)
goto ERROR;
// Store key
- r = snprintf(o->key, sizeof(o->key), "%s", key);
+ r = collecty_string_set(o->key, key);
if (r < 0)
goto ERROR;
return -errno;
// Store the protocol
- r = snprintf(proto, sizeof(proto), "%s", k);
+ r = collecty_string_set(proto, k);
if (r < 0)
return -errno;
// Even line
case 0:
// Just store the keys
- r = snprintf(keys, sizeof(keys), "%s", line);
+ r = collecty_string_set(keys, line);
if (r < 0)
goto ERROR;
break;
#include "ctx.h"
#include "daemon.h"
#include "source.h"
+#include "string.h"
#include "time.h"
#include "util.h"
static int __collecty_source_path(collecty_source* self,
const char* object, char* path, size_t length) {
- int r;
-
// Fetch the source name
const char* name = collecty_source_name(self);
if (object)
- r = snprintf(path, length, "%s/%s-%s.rrd", DATABASE_PATH, name, object);
- else
- r = snprintf(path, length, "%s/%s.rrd", DATABASE_PATH, name);
-
- // Handle errors
- if (r < 0)
- return -errno;
+ return __collecty_string_format(path, length, "%s/%s-%s.rrd", DATABASE_PATH, name, object);
- return 0;
+ return __collecty_string_format(path, length, "%s/%s.rrd", DATABASE_PATH, name);
}
/*
// Format the arguments
va_start(args, format);
- r = vsnprintf(value, sizeof(value), format, args);
+ r = collecty_string_vformat(value, format, args);
va_end(args);
// Handle errors
if (r < 0)
- return -errno;
+ return r;
// Submit the data to the daemon
return collecty_daemon_submit(self->daemon, self, object, value);
// Append the object to the field name so that we can load multiple RRD of the same source
if (object) {
- r = snprintf(field, sizeof(field), "%s_%s", ds->field, object);
+ r = collecty_string_format(field, "%s_%s", ds->field, object);
if (r < 0)
- return -errno;
+ return r;
} else {
- r = snprintf(field, sizeof(field), "%s", ds->field);
+ r = collecty_string_set(field, ds->field);
if (r < 0)
- return -errno;
+ return r;
}
// Add the classic DEF line
#define COLLECTY_STRING_H
#include <ctype.h>
+#include <errno.h>
#include <string.h>
+#include "util.h"
+
inline int collecty_string_equals(const char* s1, const char* s2) {
return strcmp(s1, s2) == 0;
}
+#define collecty_string_vformat(s, format, args) \
+ __collecty_string_vformat(s, sizeof(s), format, args)
+
+static inline int __collecty_string_vformat(char* s,
+ const size_t length, const char* format, va_list args) {
+ // Write string to buffer
+ const ssize_t required = vsnprintf(s, length, format, args);
+
+ // Catch any errors
+ if (unlikely(required < 0))
+ return -errno;
+
+ // Check if the entire string could be written
+ if (unlikely((size_t)required >= length))
+ return -ENOBUFS;
+
+ // Success
+ return 0;
+}
+
+#define collecty_string_format(s, format, ...) \
+ __collecty_string_format(s, sizeof(s), format, __VA_ARGS__)
+
+static inline int __collecty_string_format(char* s, const size_t length, const char* format, ...) {
+ va_list args;
+ int r;
+
+ // Call __collecty_string_vformat
+ va_start(args, format);
+ r = __collecty_string_vformat(s, length, format, args);
+ va_end(args);
+
+ return r;
+}
+
+#define collecty_string_set(s, value) \
+ __collecty_string_set(s, sizeof(s), value)
+
+static inline int __collecty_string_set(char* s, const size_t length, const char* value) {
+ // If value is NULL or an empty, we will overwrite the buffer with just zeros
+ if (unlikely(!value)) {
+ *s = '\0';
+ return 0;
+ }
+
+ // Copy everything until we hit the end of the input string
+ for (unsigned int i = 0; i < length; i++) {
+ s[i] = value[i];
+
+ // Done
+ if (value[i] == '\0')
+ return 0;
+ }
+
+ // It seems that the buffer was not large enough. Terminate and return an error.
+ s[length - 1] = '\0';
+
+ return -ENOBUFS;
+}
+
inline void collecty_string_lstrip(char* s) {
if (!s)
return;
#include <stdint.h>
#include <stdio.h>
+#include "string.h"
#include "util.h"
int __collecty_format_number(char* buffer, size_t length, int number) {
- int r;
-
// Format the number if positive or zero
if (number >= 0)
- r = snprintf(buffer, length, "%d", number);
+ return __collecty_string_format(buffer, length, "%d", number);
// Otherwise we set it to UNKNOWN
- else
- r = snprintf(buffer, length, "U");
-
- // Abort on error
- if (r < 0)
- return -errno;
-
- return 0;
+ return __collecty_string_set(buffer, length, "U");
}
int collecty_file_read_uint64(const char* path, uint64_t* number) {