<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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", 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