]> git.ipfire.org Git - people/ms/telemetry.git/commitdiff
command: Add a failure callback
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 4 Jun 2026 15:19:50 +0000 (15:19 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 4 Jun 2026 15:19:50 +0000 (15:19 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/command.c
src/daemon/command.h

index b27a2cf851e6076e2e9423a738b8855f26d81dd0..6c0fab55053196adc9c860fb62e96c2fb6718403 100644 (file)
@@ -79,6 +79,10 @@ struct td_command {
                // On success
                td_command_success_callback on_success;
                void* on_success_data;
+
+               // On failure
+               td_command_failure_callback on_failure;
+               void* on_failure_data;
        } callbacks;
 
        // Events
@@ -233,6 +237,12 @@ void td_command_on_success(td_command* self,
        self->callbacks.on_success_data = data;
 }
 
+void td_command_on_failure(td_command* self,
+               td_command_failure_callback callback, void* data) {
+       self->callbacks.on_failure = callback;
+       self->callbacks.on_failure_data = data;
+}
+
 // Capabilities
 static int td_command_require_cap(td_command* self, const cap_value_t cap) {
        // Check if we have space
@@ -376,6 +386,16 @@ static int td_command_exited(sd_event_source* source, const siginfo_t* si, void*
                }
        }
 
+       // Open stdout as a file
+       r = td_file_open_buffer(&stdout, self->ctx, self->stdout.buffer);
+       if (r < 0)
+               goto ERROR;
+
+       // Open a file handle
+       r = td_file_open_buffer(&stderr, self->ctx, self->stderr.buffer);
+       if (r < 0)
+               goto ERROR;
+
        switch (si->si_code) {
                case CLD_EXITED:
                        DEBUG(self->ctx, "Process has exited with status code %d\n", si->si_status);
@@ -385,11 +405,6 @@ static int td_command_exited(sd_event_source* source, const siginfo_t* si, void*
 
                        // Log stderr
                        if (rc) {
-                               // Open a file handle
-                               r = td_file_open_buffer(&stderr, self->ctx, self->stderr.buffer);
-                               if (r < 0)
-                                       goto ERROR;
-
                                // Log all lines
                                r = td_file_walk(stderr, td_command_log_stderr, self);
                                if (r < 0)
@@ -413,20 +428,23 @@ static int td_command_exited(sd_event_source* source, const siginfo_t* si, void*
                        break;
        }
 
-       // Skip any further processing if the command did not succeed
-       if (rc)
-               goto ERROR;
-
-       // Call the callback
-       if (self->callbacks.on_success) {
-               // Open stdout as a file
-               r = td_file_open_buffer(&stdout, self->ctx, self->stdout.buffer);
-               if (r < 0)
-                       goto ERROR;
+       // Call any callbacks
+       switch (rc) {
+               // Success
+               case 0:
+                       if (self->callbacks.on_success) {
+                               r = self->callbacks.on_success(self->ctx,
+                                       rc, stdout, self->callbacks.on_success_data);
+                       }
+                       break;
 
-               // Call the callback
-               r = self->callbacks.on_success(self->ctx,
-                       rc, stdout, self->callbacks.on_success_data);
+               // Failure
+               default:
+                       if (self->callbacks.on_failure) {
+                               r = self->callbacks.on_failure(self->ctx,
+                                       rc, stderr, self->callbacks.on_failure_data);
+                       }
+                       break;
        }
 
 ERROR:
index 054ebb090148df4116e20df3f324fe34526fdad3..0a9a4e9d8af0d85d687eeccbceedc3b40a551b0d 100644 (file)
@@ -30,6 +30,8 @@ typedef struct td_command td_command;
 
 typedef int (*td_command_success_callback)
        (td_ctx* ctx, int rc, td_file* stdout, void* data);
+typedef int (*td_command_failure_callback)
+       (td_ctx* ctx, int rc, td_file* stderr, void* data);
 
 #include "daemon.h"
 
@@ -46,6 +48,10 @@ void td_command_set_timeout(td_command* self, uint64_t timeout);
 void td_command_on_success(td_command* self,
        td_command_success_callback callback, void* data);
 
+// Called if the command has failed
+void td_command_on_failure(td_command* self,
+       td_command_failure_callback callback, void* data);
+
 // Capabilities
 int td_command_require_caps(td_command* self, const cap_value_t* caps);