Move termination signal handing from main into iperf_run_client

and iperf_run_server, so that API users get it too.  Also, call
iperf_errexit with an appropriate message, which in -J mode dumps
out any accumulated JSON data.
This commit is contained in:
Jef Poskanzer 2013-10-29 15:03:17 -07:00
parent 7639c1a631
commit afe6222a89
5 changed files with 53 additions and 23 deletions

View File

@ -47,8 +47,6 @@
#include "iperf_util.h"
#include "locale.h"
jmp_buf env; /* to handle longjmp on signal */
/* Forwards. */
static int send_parameters(struct iperf_test *test);
@ -2109,12 +2107,27 @@ diskfile_recv(struct iperf_stream *sp)
return r;
}
void
sig_handler(int sig)
iperf_catch_sigend(void (*handler)(int))
{
longjmp(env, 1);
signal(SIGINT, handler);
signal(SIGTERM, handler);
signal(SIGHUP, handler);
}
void
iperf_got_sigend(struct iperf_test *test)
{
if (test->ctrl_sck >= 0) {
test->state = (test->role == 'c') ? CLIENT_TERMINATE : SERVER_TERMINATE;
(void) Nwrite(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp);
}
i_errno = (test->role == 'c') ? IECLIENTTERM : IESERVERTERM;
iperf_errexit(test, "interrupt - %s", iperf_strerror(i_errno));
}
int
iperf_json_start(struct iperf_test *test)
{

View File

@ -169,7 +169,8 @@ int iperf_set_send_state(struct iperf_test *test, char state);
void iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP);
int iperf_send(struct iperf_test *, fd_set *) /* __attribute__((hot)) */;
int iperf_recv(struct iperf_test *, fd_set *);
void sig_handler(int);
void iperf_catch_sigend(void (*handler)(int));
void iperf_got_sigend(struct iperf_test *test) __attribute__ ((noreturn));
void usage();
void usage_long();
void warning(char *);

View File

@ -300,6 +300,15 @@ sigalrm_handler(int sig)
}
static jmp_buf sigend_jmp_buf;
static void
sigend_handler(int sig)
{
longjmp(sigend_jmp_buf, 1);
}
int
iperf_run_client(struct iperf_test * test)
{
@ -311,6 +320,11 @@ iperf_run_client(struct iperf_test * test)
fd_set read_set, write_set;
struct timeval now;
/* Termination signals. */
iperf_catch_sigend(sigend_handler);
if (setjmp(sigend_jmp_buf))
iperf_got_sigend(test);
if (test->affinity != -1)
if (iperf_setaffinity(test->affinity) != 0)
return -1;

View File

@ -330,6 +330,16 @@ cleanup_server(struct iperf_test *test)
close(test->listener);
}
static jmp_buf sigend_jmp_buf;
static void
sigend_handler(int sig)
{
longjmp(sigend_jmp_buf, 1);
}
int
iperf_run_server(struct iperf_test *test)
{
@ -338,6 +348,11 @@ iperf_run_server(struct iperf_test *test)
struct iperf_stream *sp;
struct timeval now;
/* Termination signals. */
iperf_catch_sigend(sigend_handler);
if (setjmp(sigend_jmp_buf))
iperf_got_sigend(test);
if (test->affinity != -1)
if (iperf_setaffinity(test->affinity) != 0)
return -1;

View File

@ -30,10 +30,10 @@
#include "net.h"
int iperf_run(struct iperf_test *);
static int run(struct iperf_test *test);
/**************************************************************************/
int
main(int argc, char **argv)
{
@ -81,19 +81,6 @@ main(int argc, char **argv)
/* This main program doesn't use SIGALRM, so the iperf API may use it. */
iperf_set_test_may_use_sigalrm(test, 1);
// XXX: Check signal for errors?
signal(SIGINT, sig_handler);
if (setjmp(env)) {
if (test->ctrl_sck >= 0) {
test->state = (test->role == 'c') ? CLIENT_TERMINATE : SERVER_TERMINATE;
if (Nwrite(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp) < 0) {
i_errno = IESENDMESSAGE;
return -1;
}
}
exit(1);
}
if (iperf_parse_arguments(test, argc, argv) < 0) {
iperf_err(test, "parameter error - %s", iperf_strerror(i_errno));
fprintf(stderr, "\n");
@ -101,7 +88,7 @@ main(int argc, char **argv)
exit(1);
}
if (iperf_run(test) < 0)
if (run(test) < 0)
iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
iperf_free_test(test);
@ -110,8 +97,8 @@ main(int argc, char **argv)
}
/**************************************************************************/
int
iperf_run(struct iperf_test * test)
static int
run(struct iperf_test *test)
{
int consecutive_errors;