Commits

Anonymous 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.

Comments (0)

Files changed (2)

cherrypy/restsrv/plugins.py

         Daemonizer(bus).subscribe()
     
     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',
             else:
                 # 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))

cherrypy/test/test_states.py

         # that we wait for the daemon to finish running before we fail.
         if exit_code != 0:
             self.fail("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 os.name 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__),
-                                  "test_states_demo.py")
-        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:
-            self.fail("Process failed to return nonzero exit code.")
-        time.sleep(2) # Wait for the daemonized process to exit.
 
 
 def run(server, conf):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.