docs: def forkandlog(function, filter='INFO5', debug=False):
      """Fork a child process and read its CASA log output.
  
      function
        A function to run in the child process
      filter
        The CASA log level filter to apply in the child process: less urgent
        messages will not be shown. Valid values are strings: "DEBUG1", "INFO5",
        ... "INFO1", "INFO", "WARN", "SEVERE".
      debug
        If true, the standard output and error of the child process are *not*
        redirected to /dev/null.
  
      Some CASA tools produce important results that are *only* provided via log
      messages. This is a problem for automation, since there’s no way for
      Python code to intercept those log messages and extract the results of
      interest. This function provides a framework for working around this
      limitation: by forking a child process and sending its log output to a
      pipe, the parent process can capture the log messages.
  
      This function is a generator. It yields lines from the child process’ CASA
      log output.
  
      Because the child process is a fork of the parent, it inherits a complete
      clone of the parent’s state at the time of forking. That means that the
      *function* argument you pass it can do just about anything you’d do in a
      regular program.
  
      The child process’ standard output and error streams are redirected to
      ``/dev/null`` unless the *debug* argument is true. Note that the CASA log
      output is redirected to a pipe that is neither of these streams. So, if
      the function raises an unhandled Python exception, the Python traceback
      will not pollute the CASA log output. But, by the same token, the calling
      program will not be able to detect that the exception occurred except by
      its impact on the expected log output.
  
      """
      import sys, os
  
      readfd, writefd = os.pipe()
      pid = os.fork()
  
      if pid == 0:
          # Child process. We never leave this branch.
          #
          # Log messages of priority >WARN are sent to stderr regardless of the
          # status of log.showconsole(). The idea is for this subprocess to be
          # something super lightweight and constrained, so it seems best to
          # nullify stderr, and stdout, to not pollute the output of the calling
          # process.
          #
          # I thought of using the default logger() setup and dup2'ing stderr to
          # the pipe fd, but then if anything else gets printed to stderr (e.g.
          # Python exception info), it'll get sent along the pipe too. The
          # caller would have to be much more complex to be able to detect and
          # handle such output.
  
          os.close(readfd)
  
          if not debug:
              f = open(os.devnull, 'w')
              os.dup2(f.fileno(), 1)
              os.dup2(f.fileno(), 2)
  
          sink = logger(filter=filter)
          sink.setlogfile(b'/dev/fd/%d' % writefd)
          function(sink)
          sys.exit(0)
  
      # Original process.
  
      os.close(writefd)
  
      with os.fdopen(readfd) as readhandle:
          for line in readhandle:
              yield line
  
      info = os.waitpid(pid, 0)
  
      if info[1]:
          # Because we're a generator, this is the only way for us to signal if
          # the process died. We could be rewritten as a context manager.
          e = RuntimeError('logging child process PID %d exited '
                           'with error code %d' % tuple(info))
          e.pid, e.exitcode = info
          raise e