Commit a55b5444 authored by Tim Pambor's avatar Tim Pambor Committed by Dan Kalowsky
Browse files

twister: Fix race condition in try_making_symlink



Replaces the check-then-create pattern for symlinks with
opportunistic creation. Instead of checking for existence
before creating the symlink, the code now attempts to
create it directly and gracefully handles the case
where it already exists.

Signed-off-by: default avatarTim Pambor <tim.pambor@codewrights.de>
(cherry picked from commit dff24c8c)
parent c1adc507
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -518,7 +518,11 @@ def try_making_symlink(source: str, link: str):
        source (str): The path to the source file.
        link (str): The path where the symbolic link should be created.
    """
    if os.path.exists(link):
    symlink_error = None

    try:
        os.symlink(source, link)
    except FileExistsError:
        if os.path.islink(link):
            if os.readlink(link) == source:
                # Link is already set up
@@ -529,19 +533,24 @@ def try_making_symlink(source: str, link: str):
            # File contents are the same
            return

        # link exists, but points to a different file, remove the link. We'll
        # try to create a new one below
        os.remove(link)

    # Create the symlink
        # link exists, but points to a different file. We'll create a new link
        # and replace it atomically with the old one
        temp_filename = f"{link}.{os.urandom(8).hex()}"
        try:
        os.symlink(source, link)
            os.symlink(source, temp_filename)
            os.replace(temp_filename, link)
        except OSError as e:
            symlink_error = e
    except OSError as e:
        symlink_error = e

    if symlink_error:
        logger.error(
            "Error creating symlink: %s, attempting to copy.", str(e)
            "Error creating symlink: %s, attempting to copy.", str(symlink_error)
        )
        shutil.copy(source, link)

        temp_filename = f"{link}.{os.urandom(8).hex()}"
        shutil.copy(source, temp_filename)
        os.replace(temp_filename, link)

def choose_gcov_tool(options, is_system_gcov):
    gcov_tool = None