commit 21bb96bf54ca192a4ae94c7a0117b098a3fec1ac Author: Mika Date: Mon Dec 8 09:42:01 2025 +0000 Add trace_agg_cli_tool/main.c diff --git a/trace_agg_cli_tool/main.c b/trace_agg_cli_tool/main.c new file mode 100644 index 0000000..ad4a859 --- /dev/null +++ b/trace_agg_cli_tool/main.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include + +/* + * trace_agg_cli_tool + * ------------------- + * Kleines Linux-CLI-Programm, das das Python-Skript "trace_agg.py" + * als Backend nutzt. Es stellt eine einfache C-CLI bereit, die + * eine Funktion "aggregate_data" nachbildet. + * + * Aufruf: + * ./trace_agg_cli_tool + * + * Verhalten: + * - Führt das Python-Skript "trace_agg.py" (im selben Verzeichnis + * wie dieses Binary) aus. + * - Übergibt die Pfade zu Eingabe- und Ausgabedatei als Argumente. + * - Gibt 0 bei Erfolg und 1 bei Fehler zurück ("boolean"-ähnlich). + * + * Hinweise: + * - Es werden keine Dateien gelöscht oder überschrieben, außer + * der explizit angegebene Ausgabepfad, den das Python-Skript + * selbst erzeugt/überschreibt. + * - Es werden keine Netzwerk-Operationen ausgeführt. + */ + +/* Hilfsfunktion: prüft, ob eine Datei existiert (lesbar). */ +static bool file_exists(const char *path) { + struct stat st; + return (stat(path, &st) == 0 && S_ISREG(st.st_mode)); +} + +/* + * aggregate_data + * -------------- + * Entspricht der im Artifact beschriebenen Funktion. + * Ruft intern das Python-Skript "trace_agg.py" auf. + * + * Parameter: + * input_file - Pfad zur Eingabedatei (CSV/Trace). + * output_file - Pfad zur Ausgabedatei. + * + * Rückgabe: + * true bei Erfolg (Exit-Code 0 vom Python-Skript), + * false bei Fehler. + */ +static bool aggregate_data(const char *input_file, const char *output_file) { + if (input_file == NULL || output_file == NULL) { + fprintf(stderr, "aggregate_data: null pointer argument\n"); + return false; + } + + if (!file_exists(input_file)) { + fprintf(stderr, "Eingabedatei existiert nicht: %s\n", input_file); + return false; + } + + /* Kommando für system(): python3 trace_agg.py */ + const char *python = "python3"; + const char *script = "trace_agg.py"; + + if (!file_exists(script)) { + fprintf(stderr, "Python-Skript nicht gefunden im aktuellen Verzeichnis: %s\n", script); + return false; + } + + /* Puffer für das aufzurufende Kommando. */ + char cmd[4096]; + + /* + * Wir quoten die Argumente sehr einfach mit einfachen Anführungszeichen, + * um Leerzeichen einigermaßen sicher zu handhaben. Für die vorgesehene + * Nutzung (lokale Pfade) ist das ausreichend. + */ + int n = snprintf(cmd, sizeof(cmd), "%s '%s' '%s' '%s'", + python, script, input_file, output_file); + if (n < 0 || (size_t)n >= sizeof(cmd)) { + fprintf(stderr, "Kommando zu lang oder Formatfehler.\n"); + return false; + } + + int ret = system(cmd); + if (ret == -1) { + perror("system"); + return false; + } + + /* system() gibt den Exit-Status kodiert zurück. Wir werten 0 als Erfolg. */ + if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) { + return true; + } + + fprintf(stderr, "trace_agg.py meldete einen Fehler (Exit-Code=%d).\n", + WIFEXITED(ret) ? WEXITSTATUS(ret) : -1); + return false; +} + +static void print_usage(const char *prog) { + fprintf(stderr, + "Nutzung: %s \n" + "Beschreibung: Ruft trace_agg.py zur Aggregation von Trace-Daten auf.\n", + prog); +} + +int main(int argc, char *argv[]) { + if (argc != 3) { + print_usage(argv[0]); + return 1; + } + + const char *input_file = argv[1]; + const char *output_file = argv[2]; + + bool ok = aggregate_data(input_file, output_file); + if (!ok) { + return 1; /* "false" im Sinne des beschriebenen API-Verhaltens */ + } + + return 0; /* Erfolg */ +}