diff --git a/src/iperf.h b/src/iperf.h index 4043031b3..cb2807a6f 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -343,6 +343,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) (struct iperf_test *, char *); /* allow 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 cae4332a2..6fbd79f84 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)(struct iperf_test *, char *)) +{ + ipt->json_callback = callback; +} + int iperf_has_zerocopy( void ) { @@ -2864,12 +2870,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)(test, 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); @@ -3060,6 +3070,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 */ @@ -5035,14 +5047,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, 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..471cc9032 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)(struct iperf_test *, char *)); 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)