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