docs: def daemonize(pidfile=None, logfile=None, sync=True):
      """ Fork the process into the background.
  
          @param pidfile: Optional PID file path.
          @param sync: Wait for parent process to disappear?
          @param logfile: Optional name of stdin/stderr log file or stream.
      """
      log = logging.getLogger("daemonize")
      ppid = os.getpid()
  
      try:
          pid = os.fork()
          if pid > 0:
              log.debug("Parent exiting (PID %d, CHILD %d)" % (ppid, pid))
              sys.exit(0)
      except OSError as exc:
          log.critical("fork #1 failed (PID %d): (%d) %s\n" % (os.getpid(), exc.errno, exc.strerror))
          sys.exit(1)
  
      ##os.chdir("/")
      ##os.umask(0022)
      os.setsid()
  
      try:
          pid = os.fork()
          if pid > 0:
              log.debug("Session leader exiting (PID %d, PPID %d, DEMON %d)" % (os.getpid(), ppid, pid))
              sys.exit(0)
      except OSError as exc:
          log.critical("fork #2 failed (PID %d): (%d) %s\n" % (os.getpid(), exc.errno, exc.strerror))
          sys.exit(1)
  
      if pidfile:
          _write_pidfile(pidfile)
  
      def sig_term(*dummy):
          "Handler for SIGTERM."
          sys.exit(0)
  
      stdin = open("/dev/null", "r")
      os.dup2(stdin.fileno(), sys.stdin.fileno())
      signal.signal(signal.SIGTERM, sig_term)
  
      if logfile:
          try:
              logfile + ""
          except TypeError:
              if logfile.fileno() != sys.stdout.fileno():
                  os.dup2(logfile.fileno(), sys.stdout.fileno())
              if logfile.fileno() != sys.stderr.fileno():
                  os.dup2(logfile.fileno(), sys.stderr.fileno())
          else:
              log.debug("Redirecting stdout / stderr to %r" % logfile)
              loghandle = open(logfile, "a+")
              os.dup2(loghandle.fileno(), sys.stdout.fileno())
              os.dup2(loghandle.fileno(), sys.stderr.fileno())
              loghandle.close()
  
      if sync:
          # Wait for 5 seconds at most, in 10ms steps
          polling = 5, .01
          for _ in range(int(polling[0] * 1 / polling[1])):
              try:
                  os.kill(ppid, 0)
              except OSError:
                  break
              else:
                  time.sleep(polling[1])
  
      log.debug("Process detached (PID %d)" % os.getpid())