#include <stdlib.h>
#include <string.h>
+#include "file.h"
#include "proc.h"
#include "string.h"
return r;
}
-int collecty_proc_read_softirq(collecty_ctx* ctx,
- collecty_proc_softirq_callback callback, void* data) {
- char* line = NULL;
- size_t length = 0;
- FILE* f = NULL;
+typedef struct collecty_proc_softirq_state {
+ // Callback
+ collecty_proc_softirq_callback callback;
+ void* data;
+
+ // Line Number
+ unsigned long lineno;
+} collecty_proc_softirq_state;
+
+static int collecty_proc_softirq_line(collecty_ctx* ctx,
+ unsigned long lineno, char* line, size_t length, void* data) {
+ collecty_proc_softirq_state* state = data;
char* e = NULL;
char* p = NULL;
char* t = NULL;
+ uint64_t v = 0;
char key[16];
- uint64_t v;
int r;
- // Open /proc/softirqs
- f = fopen("/proc/softirqs", "r");
- if (!f) {
- r = -errno;
- goto ERROR;
- }
+ // Skip the first line
+ if (!lineno++)
+ return 0;
+
+ // Fetch the key
+ t = strtok_r(line, ":", &p);
+ if (!t)
+ return -errno;
+
+ // Store the key
+ r = collecty_string_set(key, t);
+ if (r < 0)
+ return -errno;
- // Count the lines
- unsigned int lineno = 0;
+ // Strip any whitespace
+ collecty_string_strip(key);
- // Read all lines
+ // Add up all values
for (;;) {
- // Read the next line
- r = getline(&line, &length, f);
- if (r < 0)
+ // Fetch the next token
+ t = strtok_r(NULL, " ", &p);
+ if (!t)
break;
- // Skip the first line
- if (!lineno++)
- continue;
+ // Parse the token
+ v += strtoul(t, &e, 10);
- // Fetch the key
- t = strtok_r(line, ":", &p);
- if (!t) {
- r = -errno;
- goto ERROR;
- }
+ // Check if could parse the value
+ switch (*e) {
+ case '\0':
+ case '\n':
+ break;
- // Store the key
- r = collecty_string_set(key, t);
- if (r < 0) {
- r = -errno;
- goto ERROR;
+ default:
+ return -EINVAL;
}
+ }
- // Strip any whitespace
- collecty_string_strip(key);
-
- // Reset the value
- v = 0;
-
- // Add up all values
- for (;;) {
- // Fetch the next token
- t = strtok_r(NULL, " ", &p);
- if (!t)
- break;
-
- // Parse the token
- v += strtoul(t, &e, 10);
+ // Call the callback
+ return state->callback(ctx, key, v, state->data);
+}
- // Check if could parse the value
- switch (*e) {
- case '\0':
- case '\n':
- break;
+int collecty_proc_read_softirq(collecty_ctx* ctx,
+ collecty_proc_softirq_callback callback, void* data) {
+ collecty_file* file = NULL;
+ int r;
- default:
- r = -EINVAL;
- goto ERROR;
- }
- }
+ collecty_proc_softirq_state state = {
+ .callback = callback,
+ .data = data,
+ .lineno = 0,
+ };
- // Call the callback
- r = callback(ctx, key, v, data);
- if (r < 0)
- goto ERROR;
- }
+ // Open /proc/softirqs
+ r = collecty_file_open_path(&file, ctx, "/proc/softirqs");
+ if (r < 0)
+ goto ERROR;
- // Success
- r = 0;
+ // Walk through all lines
+ r = collecty_file_walk(file, collecty_proc_softirq_line, &state);
ERROR:
- if (line)
- free(line);
- if (f)
- fclose(f);
+ if (file)
+ collecty_file_unref(file);
return r;
}