Lakin Wecker  committed 188a668

Parent processes in Daemonizer should not even attempt to clean up after themselves, so use os._exit(0) instead of sys.exit(0). Updated tests and documentation to reflect the fact that if the first forkin Daemonizer completes, the process return code will always be 0.

  • Participants
  • Parent commits 6fddf33
  • Branches default

Comments (0)

Files changed (2)

File cherrypy/restsrv/

     When this component finishes, the process is completely decoupled from
-    the parent environment.
+    the parent environment.  Please note that when this component is used,
+    the return code from the parent process will always be 0, even if a
+    startup error occured, unless that error was during the daemonizing process. 
+    If you use this plugin to Daemonize, don't use the return code as an accurate
+    indication of whether the process fully started.  In fact, that return code
+    only indicates if the process succesfully finished the first fork.
     def __init__(self, bus, stdin='/dev/null', stdout='/dev/null',
                 # This is the first parent. Exit, now that we've forked.
                 self.bus.log('Forking once.')
-                sys.exit(0)
+                os._exit(0)
         except OSError, exc:
             # Python raises OSError rather than returning negative numbers.
             sys.exit("%s: fork #1 failed: (%d) %s\n"
             pid = os.fork()
             if pid > 0:
                 self.bus.log('Forking twice.')
-                sys.exit(0) # Exit second parent
+                os._exit(0) # Exit second parent
         except OSError, exc:
             sys.exit("%s: fork #2 failed: (%d) %s\n"
                      % (sys.argv[0], exc.errno, exc.strerror))

File cherrypy/test/

         # that we wait for the daemon to finish running before we fail.
         if exit_code != 0:
   "Daemonized process failed to exit cleanly")
-    def test_2_Start_Error_With_Daemonize(self):
-        if not self.server_class:
-            print "skipped (no server) ",
-            return
-        if not in ['posix']: 
-            print "skipped (not on posix) ",
-            return
-        # Start the demo script in a new process
-        demoscript = os.path.join(os.getcwd(), os.path.dirname(__file__),
-                                  "")
-        host = cherrypy.server.socket_host
-        port = cherrypy.server.socket_port
-        # If a process errors during start, it should stop the engine
-        # and exit with a non-zero exit code, even if we daemonize soon
-        # thereafter.
-        args = [sys.executable, demoscript, host, str(port), '-starterror', '-daemonize']
-        if self.scheme == "https":
-            args.append('-ssl')
-        exit_code = os.spawnl(os.P_WAIT, sys.executable, *args)
-        if exit_code == 0:
-  "Process failed to return nonzero exit code.")
-        time.sleep(2) # Wait for the daemonized process to exit.
 def run(server, conf):