(Mostly) switched error reporting to a single routine that handles JSON mode.
This commit is contained in:
parent
cda2ce2a7e
commit
b5e0751f59
@ -14,7 +14,6 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
@ -1387,15 +1386,15 @@ iperf_print_intermediate(struct iperf_test *test)
|
||||
/* sum up all streams */
|
||||
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);
|
||||
if (irp == NULL) {
|
||||
fprintf(stderr, "iperf_print_intermediate Error: interval_results is NULL\n");
|
||||
iperf_err(test, "iperf_print_intermediate error: interval_results is NULL");
|
||||
return;
|
||||
}
|
||||
bytes += irp->bytes_transferred;
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||
retransmits += irp->this_retrans;
|
||||
}
|
||||
if (bytes <=0 ) { /* this can happen if timer goes off just when client exits */
|
||||
fprintf(stderr, "error: bytes <= 0!\n");
|
||||
if (bytes <=0) { /* this can happen if timer goes off just when client exits */
|
||||
iperf_err(test, "error: bytes <= 0!");
|
||||
return;
|
||||
}
|
||||
/* next build string with sum of all streams */
|
||||
@ -1613,7 +1612,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
|
||||
|
||||
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* get last entry in linked list */
|
||||
if (irp == NULL) {
|
||||
fprintf(stderr, "print_interval_results Error: interval_results is NULL \n");
|
||||
iperf_err(test, "print_interval_results error: interval_results is NULL");
|
||||
return;
|
||||
}
|
||||
if (!test->json_output) {
|
||||
@ -1826,80 +1825,3 @@ iperf_json_finish(struct iperf_test *test)
|
||||
test->json_top = test->json_start = test->json_intervals = test->json_end = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper routine for building cJSON objects in a printf-like manner.
|
||||
**
|
||||
** Sample call:
|
||||
** j = iperf_json_printf("foo: %b bar: %d bletch: %f eep: %s", b, i, f, s);
|
||||
**
|
||||
** The four formatting characters and the types they expect are:
|
||||
** %b boolean int
|
||||
** %d integer int64_t
|
||||
** %f floating point double
|
||||
** %s string char *
|
||||
** If the values you're passing in are not these exact types, you must
|
||||
** cast them, there is no automatic type coercion/widening here.
|
||||
**
|
||||
** The colons mark the end of field names, and blanks are ignored.
|
||||
**
|
||||
** This routine is not particularly robust, but it's not part of the API,
|
||||
** it's just for internal iperf3 use.
|
||||
**
|
||||
** It currently lives in iperf_api.c, rather than iperf_util.c, because
|
||||
** putting it in iperf_util.c would mean adding -lm to more executables,
|
||||
** because the cJSON package uses libm/floor(). If I get around to fixing
|
||||
** that, then this routine can move.
|
||||
*/
|
||||
cJSON*
|
||||
iperf_json_printf(const char *format, ...)
|
||||
{
|
||||
cJSON* o;
|
||||
va_list argp;
|
||||
const char *cp;
|
||||
char name[100];
|
||||
char* np;
|
||||
cJSON* j;
|
||||
|
||||
o = cJSON_CreateObject();
|
||||
if (o == NULL)
|
||||
return NULL;
|
||||
va_start(argp, format);
|
||||
np = name;
|
||||
for (cp = format; *cp != '\0'; ++cp) {
|
||||
switch (*cp) {
|
||||
case ' ':
|
||||
break;
|
||||
case ':':
|
||||
*np = '\0';
|
||||
break;
|
||||
case '%':
|
||||
++cp;
|
||||
switch (*cp) {
|
||||
case 'b':
|
||||
j = cJSON_CreateBool(va_arg(argp, int));
|
||||
break;
|
||||
case 'd':
|
||||
j = cJSON_CreateInt(va_arg(argp, int64_t));
|
||||
break;
|
||||
case 'f':
|
||||
j = cJSON_CreateFloat(va_arg(argp, double));
|
||||
break;
|
||||
case 's':
|
||||
j = cJSON_CreateString(va_arg(argp, char *));
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
if (j == NULL)
|
||||
return NULL;
|
||||
cJSON_AddItemToObject(o, name, j);
|
||||
np = name;
|
||||
break;
|
||||
default:
|
||||
*np++ = *cp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(argp);
|
||||
return o;
|
||||
}
|
||||
|
@ -195,10 +195,10 @@ void iperf_test_reset(struct iperf_test *);
|
||||
/* JSON output routines. */
|
||||
int iperf_json_start(struct iperf_test *);
|
||||
int iperf_json_finish(struct iperf_test *);
|
||||
cJSON* iperf_json_printf(const char *format, ...);
|
||||
|
||||
/* Error routines. */
|
||||
void iperf_error(char *);
|
||||
void iperf_err(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
|
||||
void iperf_errexit(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3),noreturn));
|
||||
char *iperf_strerror(int);
|
||||
extern int i_errno;
|
||||
enum {
|
||||
|
@ -11,9 +11,47 @@
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "iperf.h"
|
||||
#include "iperf_api.h"
|
||||
|
||||
static void
|
||||
iperf_verr(struct iperf_test *test, const char *format, va_list argp)
|
||||
{
|
||||
char str[1000];
|
||||
|
||||
vsnprintf(str, sizeof(str), format, argp);
|
||||
if (test != NULL && test->json_output && test->json_top != NULL) {
|
||||
cJSON_AddStringToObject(test->json_top, "error", str);
|
||||
iperf_json_finish(test);
|
||||
} else
|
||||
fprintf(stderr, "iperf3: %s\n", str);
|
||||
}
|
||||
|
||||
/* Do a printf to stderr. */
|
||||
void
|
||||
iperf_err(struct iperf_test *test, const char *format, ...)
|
||||
{
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, format);
|
||||
iperf_verr(test, format, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
/* Do a printf to stderr, then exit. */
|
||||
void
|
||||
iperf_errexit(struct iperf_test *test, const char *format, ...)
|
||||
{
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, format);
|
||||
iperf_verr(test, format, argp);
|
||||
va_end(argp);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int i_errno;
|
||||
|
||||
char *
|
||||
@ -28,198 +66,198 @@ iperf_strerror(int i_errno)
|
||||
|
||||
switch (i_errno) {
|
||||
case IENONE:
|
||||
snprintf(errstr, len, "No error");
|
||||
snprintf(errstr, len, "no error");
|
||||
break;
|
||||
case IESERVCLIENT:
|
||||
snprintf(errstr, len, "Iperf cannot be both server and client");
|
||||
snprintf(errstr, len, "cannot be both server and client");
|
||||
break;
|
||||
case IENOROLE:
|
||||
snprintf(errstr, len, "Iperf instance must either be a client (-c) or server (-s)");
|
||||
snprintf(errstr, len, "must either be a client (-c) or server (-s)");
|
||||
break;
|
||||
case IECLIENTONLY:
|
||||
snprintf(errstr, len, "Some option you are trying to set is client only");
|
||||
snprintf(errstr, len, "some option you are trying to set is client only");
|
||||
break;
|
||||
case IEDURATION:
|
||||
snprintf(errstr, len, "Test duration too long (maximum = %d seconds)", MAX_TIME);
|
||||
snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME);
|
||||
break;
|
||||
case IENUMSTREAMS:
|
||||
snprintf(errstr, len, "Number of parallel streams too large (maximum = %d)", MAX_STREAMS);
|
||||
snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS);
|
||||
break;
|
||||
case IEBLOCKSIZE:
|
||||
snprintf(errstr, len, "Block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
|
||||
snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
|
||||
break;
|
||||
case IEBUFSIZE:
|
||||
snprintf(errstr, len, "Socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
|
||||
snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
|
||||
break;
|
||||
case IEINTERVAL:
|
||||
snprintf(errstr, len, "Report interval too large (maximum = %d seconds)", MAX_INTERVAL);
|
||||
snprintf(errstr, len, "report interval too large (maximum = %d seconds)", MAX_INTERVAL);
|
||||
break;
|
||||
case IEMSS:
|
||||
snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
|
||||
break;
|
||||
case IENEWTEST:
|
||||
snprintf(errstr, len, "Unable to create a new test");
|
||||
snprintf(errstr, len, "unable to create a new test");
|
||||
perr = 1;
|
||||
break;
|
||||
case IEINITTEST:
|
||||
snprintf(errstr, len, "Test initialization failed");
|
||||
snprintf(errstr, len, "test initialization failed");
|
||||
perr = 1;
|
||||
break;
|
||||
case IELISTEN:
|
||||
snprintf(errstr, len, "Unable to start listener for connections");
|
||||
snprintf(errstr, len, "unable to start listener for connections");
|
||||
perr = 1;
|
||||
break;
|
||||
case IECONNECT:
|
||||
snprintf(errstr, len, "Unable to connect to server");
|
||||
snprintf(errstr, len, "unable to connect to server");
|
||||
herr = 1;
|
||||
perr = 1;
|
||||
break;
|
||||
case IEACCEPT:
|
||||
snprintf(errstr, len, "Unable to accept connection from client");
|
||||
snprintf(errstr, len, "unable to accept connection from client");
|
||||
herr = 1;
|
||||
perr = 1;
|
||||
break;
|
||||
case IESENDCOOKIE:
|
||||
snprintf(errstr, len, "Unable to send cookie to server");
|
||||
snprintf(errstr, len, "unable to send cookie to server");
|
||||
perr = 1;
|
||||
break;
|
||||
case IERECVCOOKIE:
|
||||
snprintf(errstr, len, "Unable to receive cookie to server");
|
||||
snprintf(errstr, len, "unable to receive cookie to server");
|
||||
perr = 1;
|
||||
break;
|
||||
case IECTRLWRITE:
|
||||
snprintf(errstr, len, "Unable to write to the control socket");
|
||||
snprintf(errstr, len, "unable to write to the control socket");
|
||||
perr = 1;
|
||||
break;
|
||||
case IECTRLREAD:
|
||||
snprintf(errstr, len, "Unable to read from the control socket");
|
||||
snprintf(errstr, len, "unable to read from the control socket");
|
||||
perr = 1;
|
||||
break;
|
||||
case IECTRLCLOSE:
|
||||
snprintf(errstr, len, "Control socket has closed unexpectedly");
|
||||
snprintf(errstr, len, "control socket has closed unexpectedly");
|
||||
break;
|
||||
case IEMESSAGE:
|
||||
snprintf(errstr, len, "Received an unknown control message");
|
||||
snprintf(errstr, len, "received an unknown control message");
|
||||
break;
|
||||
case IESENDMESSAGE:
|
||||
snprintf(errstr, len, "Unable to send control message");
|
||||
snprintf(errstr, len, "unable to send control message");
|
||||
perr = 1;
|
||||
break;
|
||||
case IERECVMESSAGE:
|
||||
snprintf(errstr, len, "Unable to receive control message");
|
||||
snprintf(errstr, len, "unable to receive control message");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESENDPARAMS:
|
||||
snprintf(errstr, len, "Unable to send parameters to server");
|
||||
snprintf(errstr, len, "unable to send parameters to server");
|
||||
perr = 1;
|
||||
break;
|
||||
case IERECVPARAMS:
|
||||
snprintf(errstr, len, "Unable to receive parameters from client");
|
||||
snprintf(errstr, len, "unable to receive parameters from client");
|
||||
perr = 1;
|
||||
break;
|
||||
case IEPACKAGERESULTS:
|
||||
snprintf(errstr, len, "Unable to package results");
|
||||
snprintf(errstr, len, "unable to package results");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESENDRESULTS:
|
||||
snprintf(errstr, len, "Unable to send results");
|
||||
snprintf(errstr, len, "unable to send results");
|
||||
perr = 1;
|
||||
break;
|
||||
case IERECVRESULTS:
|
||||
snprintf(errstr, len, "Unable to receive results");
|
||||
snprintf(errstr, len, "unable to receive results");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESELECT:
|
||||
snprintf(errstr, len, "Select failed");
|
||||
snprintf(errstr, len, "select failed");
|
||||
perr = 1;
|
||||
break;
|
||||
case IECLIENTTERM:
|
||||
snprintf(errstr, len, "The client has terminated");
|
||||
snprintf(errstr, len, "the client has terminated");
|
||||
break;
|
||||
case IESERVERTERM:
|
||||
snprintf(errstr, len, "The server has terminated");
|
||||
snprintf(errstr, len, "the server has terminated");
|
||||
break;
|
||||
case IEACCESSDENIED:
|
||||
snprintf(errstr, len, "The server is busy running a test. try again later");
|
||||
snprintf(errstr, len, "the server is busy running a test. try again later");
|
||||
break;
|
||||
case IESETNODELAY:
|
||||
snprintf(errstr, len, "Unable to set TCP NODELAY");
|
||||
snprintf(errstr, len, "unable to set TCP NODELAY");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESETMSS:
|
||||
snprintf(errstr, len, "Unable to set TCP MSS");
|
||||
snprintf(errstr, len, "unable to set TCP MSS");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESETBUF:
|
||||
snprintf(errstr, len, "Unable to set socket buffer size");
|
||||
snprintf(errstr, len, "unable to set socket buffer size");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESETTOS:
|
||||
snprintf(errstr, len, "Unable to set IP TOS");
|
||||
snprintf(errstr, len, "unable to set IP TOS");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESETCOS:
|
||||
snprintf(errstr, len, "Unable to set IPv6 traffic class");
|
||||
snprintf(errstr, len, "unable to set IPv6 traffic class");
|
||||
perr = 1;
|
||||
break;
|
||||
case IEREUSEADDR:
|
||||
snprintf(errstr, len, "Unable to reuse address on socket");
|
||||
snprintf(errstr, len, "unable to reuse address on socket");
|
||||
perr = 1;
|
||||
break;
|
||||
case IENONBLOCKING:
|
||||
snprintf(errstr, len, "Unable to set socket to non-blocking");
|
||||
snprintf(errstr, len, "unable to set socket to non-blocking");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESETWINDOWSIZE:
|
||||
snprintf(errstr, len, "Unable to set socket window size");
|
||||
snprintf(errstr, len, "unable to set socket window size");
|
||||
perr = 1;
|
||||
break;
|
||||
case IEPROTOCOL:
|
||||
snprintf(errstr, len, "Protocol does not exist");
|
||||
snprintf(errstr, len, "protocol does not exist");
|
||||
break;
|
||||
case IECREATESTREAM:
|
||||
snprintf(errstr, len, "Unable to create a new stream");
|
||||
snprintf(errstr, len, "unable to create a new stream");
|
||||
herr = 1;
|
||||
perr = 1;
|
||||
break;
|
||||
case IEINITSTREAM:
|
||||
snprintf(errstr, len, "Unable to initialize stream");
|
||||
snprintf(errstr, len, "unable to initialize stream");
|
||||
herr = 1;
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMLISTEN:
|
||||
snprintf(errstr, len, "Unable to start stream listener");
|
||||
snprintf(errstr, len, "unable to start stream listener");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMCONNECT:
|
||||
snprintf(errstr, len, "Unable to connect stream");
|
||||
snprintf(errstr, len, "unable to connect stream");
|
||||
herr = 1;
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMACCEPT:
|
||||
snprintf(errstr, len, "Unable to accept stream connection");
|
||||
snprintf(errstr, len, "unable to accept stream connection");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMWRITE:
|
||||
snprintf(errstr, len, "Unable to write to stream socket");
|
||||
snprintf(errstr, len, "unable to write to stream socket");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMREAD:
|
||||
snprintf(errstr, len, "Unable to read from stream socket");
|
||||
snprintf(errstr, len, "unable to read from stream socket");
|
||||
perr = 1;
|
||||
break;
|
||||
case IESTREAMCLOSE:
|
||||
snprintf(errstr, len, "Stream socket has closed unexpectedly");
|
||||
snprintf(errstr, len, "stream socket has closed unexpectedly");
|
||||
break;
|
||||
case IESTREAMID:
|
||||
snprintf(errstr, len, "Stream has an invalid id");
|
||||
snprintf(errstr, len, "stream has an invalid id");
|
||||
break;
|
||||
case IENEWTIMER:
|
||||
snprintf(errstr, len, "Unable to create new timer");
|
||||
snprintf(errstr, len, "unable to create new timer");
|
||||
perr = 1;
|
||||
break;
|
||||
case IEUPDATETIMER:
|
||||
snprintf(errstr, len, "Unable to update timer");
|
||||
snprintf(errstr, len, "unable to update timer");
|
||||
perr = 1;
|
||||
break;
|
||||
}
|
||||
@ -234,9 +272,3 @@ iperf_strerror(int i_errno)
|
||||
|
||||
return errstr;
|
||||
}
|
||||
|
||||
void
|
||||
iperf_error(char *estr)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", estr, iperf_strerror(i_errno));
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
// XXX: Need to rethink how this behaves to fit API
|
||||
if ((rval = Nread(test->ctrl_sck, &test->state, sizeof(char), Ptcp)) <= 0) {
|
||||
if (rval == 0) {
|
||||
fprintf(stderr, "The client has unexpectedly closed the connection.\n");
|
||||
iperf_err(test, "the client has unexpectedly closed the connection");
|
||||
i_errno = IECTRLCLOSE;
|
||||
test->state = IPERF_DONE;
|
||||
return 0;
|
||||
@ -202,7 +202,7 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
i_errno = IECLIENTTERM;
|
||||
|
||||
// XXX: Remove this line below!
|
||||
fprintf(stderr, "The client has terminated.\n");
|
||||
iperf_err(test, "the client has terminated");
|
||||
SLIST_FOREACH(sp, &test->streams, streams) {
|
||||
FD_CLR(sp->socket, &test->read_set);
|
||||
FD_CLR(sp->socket, &test->write_set);
|
||||
|
@ -67,7 +67,7 @@ iperf_udp_recv(struct iperf_stream *sp)
|
||||
sp->packet_count = pcount;
|
||||
} else {
|
||||
sp->outoforder_packets++;
|
||||
fprintf(stderr, "OUT OF ORDER - incoming packet = %d and received packet = %d AND SP = %d\n", pcount, sp->packet_count, sp->socket);
|
||||
iperf_err(sp->test, "OUT OF ORDER - incoming packet = %d and received packet = %d AND SP = %d", pcount, sp->packet_count, sp->socket);
|
||||
}
|
||||
|
||||
/* jitter measurement */
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
@ -24,6 +25,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cjson.h"
|
||||
|
||||
/* make_cookie
|
||||
*
|
||||
@ -177,3 +179,75 @@ cpu_util(double *pcpu)
|
||||
|
||||
*pcpu = ((ctemp - clast) / timediff) * 100;
|
||||
}
|
||||
|
||||
/* Helper routine for building cJSON objects in a printf-like manner.
|
||||
**
|
||||
** Sample call:
|
||||
** j = iperf_json_printf("foo: %b bar: %d bletch: %f eep: %s", b, i, f, s);
|
||||
**
|
||||
** The four formatting characters and the types they expect are:
|
||||
** %b boolean int
|
||||
** %d integer int64_t
|
||||
** %f floating point double
|
||||
** %s string char *
|
||||
** If the values you're passing in are not these exact types, you must
|
||||
** cast them, there is no automatic type coercion/widening here.
|
||||
**
|
||||
** The colons mark the end of field names, and blanks are ignored.
|
||||
**
|
||||
** This routine is not particularly robust, but it's not part of the API,
|
||||
** it's just for internal iperf3 use.
|
||||
*/
|
||||
cJSON*
|
||||
iperf_json_printf(const char *format, ...)
|
||||
{
|
||||
cJSON* o;
|
||||
va_list argp;
|
||||
const char *cp;
|
||||
char name[100];
|
||||
char* np;
|
||||
cJSON* j;
|
||||
|
||||
o = cJSON_CreateObject();
|
||||
if (o == NULL)
|
||||
return NULL;
|
||||
va_start(argp, format);
|
||||
np = name;
|
||||
for (cp = format; *cp != '\0'; ++cp) {
|
||||
switch (*cp) {
|
||||
case ' ':
|
||||
break;
|
||||
case ':':
|
||||
*np = '\0';
|
||||
break;
|
||||
case '%':
|
||||
++cp;
|
||||
switch (*cp) {
|
||||
case 'b':
|
||||
j = cJSON_CreateBool(va_arg(argp, int));
|
||||
break;
|
||||
case 'd':
|
||||
j = cJSON_CreateInt(va_arg(argp, int64_t));
|
||||
break;
|
||||
case 'f':
|
||||
j = cJSON_CreateFloat(va_arg(argp, double));
|
||||
break;
|
||||
case 's':
|
||||
j = cJSON_CreateString(va_arg(argp, char *));
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
if (j == NULL)
|
||||
return NULL;
|
||||
cJSON_AddItemToObject(o, name, j);
|
||||
np = name;
|
||||
break;
|
||||
default:
|
||||
*np++ = *cp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(argp);
|
||||
return o;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef __IPERF_UTIL_H
|
||||
#define __IPERF_UTIL_H
|
||||
|
||||
#include "cjson.h"
|
||||
|
||||
void make_cookie(char *);
|
||||
|
||||
int is_closed(int);
|
||||
@ -24,4 +26,6 @@ int delay(int64_t ns);
|
||||
|
||||
void cpu_util(double *);
|
||||
|
||||
cJSON* iperf_json_printf(const char *format, ...);
|
||||
|
||||
#endif
|
||||
|
22
src/main.c
22
src/main.c
@ -74,10 +74,8 @@ main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
test = iperf_new_test();
|
||||
if (!test) {
|
||||
iperf_error("create new test error");
|
||||
exit(1);
|
||||
}
|
||||
if (!test)
|
||||
iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno));
|
||||
iperf_defaults(test); /* sets defaults */
|
||||
|
||||
// XXX: Check signal for errors?
|
||||
@ -94,16 +92,14 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (iperf_parse_arguments(test, argc, argv) < 0) {
|
||||
iperf_error("parameter error");
|
||||
iperf_err(test, "parameter error - %s", iperf_strerror(i_errno));
|
||||
fprintf(stderr, "\n");
|
||||
usage_long();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (iperf_run(test) < 0) {
|
||||
iperf_error("error");
|
||||
exit(1);
|
||||
}
|
||||
if (iperf_run(test) < 0)
|
||||
iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
|
||||
|
||||
iperf_free_test(test);
|
||||
|
||||
@ -144,17 +140,15 @@ iperf_run(struct iperf_test * test)
|
||||
case 's':
|
||||
for (;;) {
|
||||
if (iperf_run_server(test) < 0) {
|
||||
iperf_error("error");
|
||||
iperf_err(test, "error - %s", iperf_strerror(i_errno));
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
iperf_reset_test(test);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (iperf_run_client(test) < 0) {
|
||||
iperf_error("error");
|
||||
exit(1);
|
||||
}
|
||||
if (iperf_run_client(test) < 0)
|
||||
iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
|
Loading…
Reference in New Issue
Block a user