--- /dev/null
+From 7c0ac64ebea38d0d9ff4d160db4d33bc087a3490 Mon Sep 17 00:00:00 2001
+From: Robert McMahon <rjmcmahon@rjmcmahon.com>
+Date: Mon, 16 Jul 2018 17:51:29 -0700
+Subject: [PATCH] fix latent bug in signal handling, per POSIX calling exit()
+ in signal handler is not safe. Use _exit() instead. Also, detect the user
+ signal SIGINT for the case of server needing two invocations to stop server
+ threads. Note: the server threads still need some work from graceful
+ termination with a single ctrl-c
+
+---
+
+--- a/compat/signal.c
++++ b/compat/signal.c
+@@ -171,7 +171,7 @@ void sig_exit( int inSigno ) {
+ static int num = 0;
+ if ( num++ == 0 ) {
+ fflush( 0 );
+- exit( 0 );
++ _exit(0);
+ }
+ } /* end sig_exit */
+
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -268,7 +268,7 @@ void Sig_Interupt( int inSigno ) {
+ // We try to not allow a single interrupt handled by multiple threads
+ // to completely kill the app so we save off the first thread ID
+ // then that is the only thread that can supply the next interrupt
+- if ( thread_equalid( sThread, thread_zeroid() ) ) {
++ if ( (inSigno == SIGINT) && thread_equalid( sThread, thread_zeroid() ) ) {
+ sThread = thread_getid();
+ } else if ( thread_equalid( sThread, thread_getid() ) ) {
+ sig_exit( inSigno );
+@@ -420,9 +420,3 @@ VOID ServiceStop() {
+ }
+
+ #endif
+-
+-
+-
+-
+-
+-
--- /dev/null
+From 755be8bdb48d2536e39d2d7cf84e8a8f86b8776f Mon Sep 17 00:00:00 2001
+From: Robert McMahon <rjmcmahon@rjmcmahon.com>
+Date: Sat, 6 Oct 2018 13:36:52 -0700
+Subject: [PATCH] cleanup main startup, fix daemon mode per redirecting stdin,
+ stderr and stdout to /dev/null
+
+---
+
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -167,67 +167,7 @@ int main( int argc, char **argv ) {
+ Settings_ParseCommandLine( argc, argv, ext_gSettings );
+
+ // Check for either having specified client or server
+- if ( ext_gSettings->mThreadMode == kMode_Client
+- || ext_gSettings->mThreadMode == kMode_Listener ) {
+-#ifdef WIN32
+- // Start the server as a daemon
+- if ( isDaemon( ext_gSettings )) {
+- if (ext_gSettings->mThreadMode == kMode_Listener) {
+- CmdInstallService(argc, argv);
+- } else {
+- fprintf(stderr, "Client cannot be run as a daemon\n");
+- }
+- return 0;
+- }
+-
+- // Remove the Windows service if requested
+- if ( isRemoveService( ext_gSettings ) ) {
+- // remove the service
+- if ( CmdRemoveService() ) {
+- fprintf(stderr, "IPerf Service is removed.\n");
+- return 0;
+- }
+- }
+-#else
+- if ( isDaemon( ext_gSettings ) ) {
+- if (ext_gSettings->mThreadMode != kMode_Listener) {
+- fprintf(stderr, "Iperf client cannot be run as a daemon\n");
+- return 0;
+- }
+- if (daemon(1, 1) < 0) {
+- perror("daemon");
+- }
+- fprintf( stderr, "Running Iperf Server as a daemon\n");
+- fprintf( stderr, "The Iperf daemon process ID : %d\n",((int)getpid()));
+- fclose(stdout);
+- fclose(stderr);
+- fclose(stdin);
+- }
+-#endif
+- // initialize client(s)
+- if ( ext_gSettings->mThreadMode == kMode_Client ) {
+- client_init( ext_gSettings );
+- }
+-
+-#ifdef HAVE_THREAD
+- // start up the reporter and client(s) or listener
+- {
+- thread_Settings *into = NULL;
+- // Create the settings structure for the reporter thread
+- Settings_Copy( ext_gSettings, &into );
+- into->mThreadMode = kMode_Reporter;
+-
+- // Have the reporter launch the client or listener
+- into->runNow = ext_gSettings;
+-
+- // Start all the threads that are ready to go
+- thread_start( into );
+- }
+-#else
+- // No need to make a reporter thread because we don't have threads
+- thread_start( ext_gSettings );
+-#endif
+- } else {
++ if ((ext_gSettings->mThreadMode != kMode_Client) && (ext_gSettings->mThreadMode != kMode_Listener)) {
+ // neither server nor client mode was specified
+ // print usage and exit
+
+@@ -236,20 +176,75 @@ int main( int argc, char **argv ) {
+ // Starting in 2.0 to restart a previously defined service
+ // you must call iperf with "iperf -D" or using the environment variable
+ SERVICE_TABLE_ENTRY dispatchTable[] =
+- {
+- { (LPSTR)TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
+- { NULL, NULL}
+- };
++ {
++ { (LPSTR)TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
++ { NULL, NULL}
++ };
+
+ // starting the service by SCM, there is no arguments will be passed in.
+ // the arguments will pass into Service_Main entry.
+ if (!StartServiceCtrlDispatcher(dispatchTable) )
+ // If the service failed to start then print usage
+ #endif
+- fprintf( stderr, usage_short, argv[0], argv[0] );
++ fprintf( stderr, usage_short, argv[0], argv[0] );
++ return 0;
++ }
++
++
++ switch (ext_gSettings->mThreadMode) {
++ case kMode_Client :
++ if ( isDaemon( ext_gSettings ) ) {
++ fprintf(stderr, "Iperf client cannot be run as a daemon\n");
++ return 0;
++ }
++ // initialize client(s)
++ client_init( ext_gSettings );
++ break;
++ case kMode_Listener :
++ if ( isDaemon( ext_gSettings ) ) {
++ fprintf( stderr, "Running Iperf Server as a daemon\n");
++ // Start the server as a daemon
++#ifdef WIN32
++ CmdInstallService(argc, argv);
++ // Remove the Windows service if requested
++ if ( isRemoveService( ext_gSettings ) ) {
++ // remove the service
++ if ( CmdRemoveService() ) {
++ fprintf(stderr, "IPerf Service is removed.\n");
++ return 0;
++ }
++ }
++#else
++ fflush(stderr);
++ // redirect stdin, stdout and sterr to /dev/null (see dameon and no close flag)
++ if (daemon(1, 0) < 0) {
++ perror("daemon");
++ }
++ }
++#endif
++ break;
++ default :
++ fprintf( stderr, "unknown mode");
++ break;
++ }
++#ifdef HAVE_THREAD
++ // start up the reporter and client(s) or listener
++ {
++ thread_Settings *into = NULL;
++ // Create the settings structure for the reporter thread
++ Settings_Copy( ext_gSettings, &into );
++ into->mThreadMode = kMode_Reporter;
++
++ // Have the reporter launch the client or listener
++ into->runNow = ext_gSettings;
+
+- return 0;
++ // Start all the threads that are ready to go
++ thread_start( into );
+ }
++#else
++ // No need to make a reporter thread because we don't have threads
++ thread_start( ext_gSettings );
++#endif
+
+ // wait for other (client, server) threads to complete
+ thread_joinall();