+++ /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();