From 5a5957f63f8e053049f764bd05792992c94922ba Mon Sep 17 00:00:00 2001 From: DavidBar-On Date: Sun, 17 Nov 2024 10:51:45 +0200 Subject: [PATCH] Add callback function to get JSON strings instead of writing them to the output file --- src/iperf.h | 2 ++ src/iperf_api.c | 42 +++++++++++++++++++++++++++++------------- src/iperf_api.h | 3 ++- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/iperf.h b/src/iperf.h index 7d14a3453..157018303 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -342,6 +342,8 @@ struct iperf_test int verbose; /* -V option - verbose mode */ int json_output; /* -J option - JSON output */ int json_stream; /* --json-stream */ + void (*json_callback) (char *); /* used by user apps to receive the JSON strings, + instead of writing them to the output file */ int zerocopy; /* -Z option - use sendfile */ int debug; /* -d option - enable debug */ enum debug_level debug_level; /* -d option option - level of debug messages to show */ diff --git a/src/iperf_api.c b/src/iperf_api.c index 34f08bc81..bd9523957 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -697,6 +697,12 @@ iperf_set_test_json_stream(struct iperf_test *ipt, int json_stream) ipt->json_stream = json_stream; } +void +iperf_set_test_json_callback(struct iperf_test *ipt, void (*callback)()) +{ + ipt->json_callback = callback; +} + int iperf_has_zerocopy( void ) { @@ -2821,12 +2827,16 @@ JSONStream_Output(struct iperf_test * test, const char * event_name, cJSON * obj char *str = cJSON_PrintUnformatted(event); if (str == NULL) return -1; - if (pthread_mutex_lock(&(test->print_mutex)) != 0) { - perror("iperf_json_finish: pthread_mutex_lock"); - } - fprintf(test->outfile, "%s\n", str); - if (pthread_mutex_unlock(&(test->print_mutex)) != 0) { - perror("iperf_json_finish: pthread_mutex_unlock"); + if (test->json_callback != NULL) { + (test->json_callback)(str); + } else { + if (pthread_mutex_lock(&(test->print_mutex)) != 0) { + perror("iperf_json_finish: pthread_mutex_lock"); + } + fprintf(test->outfile, "%s\n", str); + if (pthread_mutex_unlock(&(test->print_mutex)) != 0) { + perror("iperf_json_finish: pthread_mutex_unlock"); + } } iflush(test); cJSON_free(str); @@ -3017,6 +3027,8 @@ iperf_defaults(struct iperf_test *testp) testp->settings->rcv_timeout.usecs = (DEFAULT_NO_MSG_RCVD_TIMEOUT % SEC_TO_mS) * mS_TO_US; testp->zerocopy = 0; + testp->json_callback = NULL; + memset(testp->cookie, 0, COOKIE_SIZE); testp->multisend = 10; /* arbitrary */ @@ -4989,14 +5001,18 @@ iperf_json_finish(struct iperf_test *test) if (test->json_output_string == NULL) { return -1; } - if (pthread_mutex_lock(&(test->print_mutex)) != 0) { - perror("iperf_json_finish: pthread_mutex_lock"); - } - fprintf(test->outfile, "%s\n", test->json_output_string); - if (pthread_mutex_unlock(&(test->print_mutex)) != 0) { - perror("iperf_json_finish: pthread_mutex_unlock"); + if (test->json_callback != NULL) { + (test->json_callback)(test->json_output_string); + } else { + if (pthread_mutex_lock(&(test->print_mutex)) != 0) { + perror("iperf_json_finish: pthread_mutex_lock"); + } + fprintf(test->outfile, "%s\n", test->json_output_string); + if (pthread_mutex_unlock(&(test->print_mutex)) != 0) { + perror("iperf_json_finish: pthread_mutex_unlock"); + } + iflush(test); } - iflush(test); } cJSON_Delete(test->json_top); } diff --git a/src/iperf_api.h b/src/iperf_api.h index 2b71613e9..8d4613d61 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -197,6 +197,7 @@ void iperf_set_test_template( struct iperf_test *ipt, const char *tmp_templat void iperf_set_test_reverse( struct iperf_test* ipt, int reverse ); void iperf_set_test_json_output( struct iperf_test* ipt, int json_output ); void iperf_set_test_json_stream( struct iperf_test* ipt, int json_stream ); +void iperf_set_test_json_callback(struct iperf_test *ipt, void (*callback)()); int iperf_has_zerocopy( void ); void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy ); void iperf_set_test_get_server_output( struct iperf_test* ipt, int get_server_output ); @@ -419,7 +420,7 @@ enum { IERVRSONLYRCVTIMEOUT = 32, // Client receive timeout is valid only in reverse mode IESNDTIMEOUT = 33, // Illegal message send timeout IEUDPFILETRANSFER = 34, // Cannot transfer file using UDP - IESERVERAUTHUSERS = 35, // Cannot access authorized users file + IESERVERAUTHUSERS = 35, // Cannot access authorized users file /* Test errors */ IENEWTEST = 100, // Unable to create a new test (check perror) IEINITTEST = 101, // Test initialization failed (check perror)