Extract a regular file member using cat for async-like I/O

    Mostly adapted from tarfile.py.

def cat_extract(tar, member, targetpath):
    """Extract a regular file member using cat for async-like I/O

    Mostly adapted from tarfile.py.

    """
    assert member.isreg()

    # Fetch the TarInfo object for the given name and build the
    # destination pathname, replacing forward slashes to platform
    # specific separators.
    targetpath = targetpath.rstrip("/")
    targetpath = targetpath.replace("/", os.sep)

    # Create all upper directories.
    upperdirs = os.path.dirname(targetpath)
    if upperdirs and not os.path.exists(upperdirs):
        try:
            # Create directories that are not part of the archive with
            # default permissions.
            os.makedirs(upperdirs)
        except EnvironmentError as e:
            if e.errno == errno.EEXIST:
                # Ignore an error caused by the race of
                # the directory being created between the
                # check for the path and the creation.
                pass
            else:
                raise

    with files.DeleteOnError(targetpath) as dest:
        with pipeline.get_cat_pipeline(pipeline.PIPE, dest.f) as pl:
            fp = tar.extractfile(member)
            copyfileobj.copyfileobj(fp, pl.stdin)

    if sys.version_info < (3, 5):
        tar.chown(member, targetpath)
    else:
        tar.chown(member, targetpath, False)

    tar.chmod(member, targetpath)
    tar.utime(member, targetpath)