From: Michael Tremer Date: Tue, 7 Oct 2025 10:05:58 +0000 (+0000) Subject: file: Add an abstraction to read files X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db49798a7d2be00c116d387b1f8c6285a051c867;p=telemetry.git file: Add an abstraction to read files Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index ffcfc8c..07a9660 100644 --- a/Makefile.am +++ b/Makefile.am @@ -101,6 +101,8 @@ dist_collectyd_SOURCES = \ src/daemon/ctx.h \ src/daemon/daemon.c \ src/daemon/daemon.h \ + src/daemon/file.c \ + src/daemon/file.h \ src/daemon/graph.c \ src/daemon/graph.h \ src/daemon/graph-bus.c \ diff --git a/src/daemon/file.c b/src/daemon/file.c new file mode 100644 index 0000000..ff69356 --- /dev/null +++ b/src/daemon/file.c @@ -0,0 +1,148 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# 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, either version 3 of the License, or # +# (at your option) any later version. # +# # +# 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. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include +#include +#include +#include + +#include "ctx.h" +#include "file.h" +#include "string.h" + +struct collecty_file { + collecty_ctx* ctx; + int nrefs; + + // File Handle + FILE* f; +}; + +static void collecty_file_free(collecty_file* self) { + if (self->f) + fclose(self->f); + if (self->ctx) + collecty_ctx_unref(self->ctx); + free(self); +} + +static int collecty_file_create(collecty_file** file, collecty_ctx* ctx) { + collecty_file* self = NULL; + + // Allocate some memory + self = calloc(1, sizeof(*self)); + if (!self) + return -errno; + + // Initialize the reference counter + self->nrefs = 1; + + // Store a reference to the context + self->ctx = collecty_ctx_ref(ctx); + + // Return the pointer + *file = self; + return 0; +} + +int collecty_file_open_path(collecty_file** file, collecty_ctx* ctx, const char* path) { + collecty_file* self = NULL; + int r; + + // Create a new object + r = collecty_file_create(&self, ctx); + if (r < 0) + goto ERROR; + + // Open the file + self->f = fopen(path, "r"); + if (!self->f) { + ERROR(ctx, "Failed to open %s: %m\n", path); + r = -errno; + goto ERROR; + } + + // Return the pointer + *file = self; + return 0; + +ERROR: + if (self) + collecty_file_unref(self); + + return r; +} + +collecty_file* collecty_file_ref(collecty_file* self) { + ++self->nrefs; + return self; +} + +collecty_file* collecty_file_unref(collecty_file* self) { + if (--self->nrefs > 0) + return self; + + collecty_file_free(self); + return NULL; +} + +int collecty_file_walk(collecty_file* self, + collecty_file_walk_callback callback, void* data) { + unsigned long lineno = 0; + char* line = NULL; + size_t length = 0; + size_t l = 0; + int r; + + // Start at the beginning of the stream + r = fseek(self->f, 0L, SEEK_SET); + if (r < 0) + return -errno; + + // Walk through all lines + for (;;) { + // Fetch the next line + r = getline(&line, &length, self->f); + if (r < 0) { + // Reset r if have reached the end of the file + if (feof(self->f)) + r = 0; + + break; + } + + // Remove the trailing newline + collecty_string_rstrip(line); + + // Determine the length of the line + l = strlen(line); + + // Call the callback + r = callback(self->ctx, lineno++, line, l, data); + if (r < 0) + break; + } + + // Cleanup + if (line) + free(line); + + return r; +} diff --git a/src/daemon/file.h b/src/daemon/file.h new file mode 100644 index 0000000..4b50431 --- /dev/null +++ b/src/daemon/file.h @@ -0,0 +1,39 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# 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, either version 3 of the License, or # +# (at your option) any later version. # +# # +# 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. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef COLLECTY_FILE_H +#define COLLECTY_FILE_H + +typedef struct collecty_file collecty_file; + +#include "ctx.h" + +int collecty_file_open_path(collecty_file** file, collecty_ctx* ctx, const char* path); + +collecty_file* collecty_file_ref(collecty_file* self); +collecty_file* collecty_file_unref(collecty_file* self); + +typedef int (*collecty_file_walk_callback) + (collecty_ctx* ctx, unsigned long lineno, char* line, size_t length, void* data); + +int collecty_file_walk(collecty_file* self, + collecty_file_walk_callback callback, void* data); + +#endif /* COLLECTY_FILE_H */