import threading


def run_with_timeout(proc, timeout, input=None):
    """
    Run Popen process with given timeout. Kills the process if it does
    not finish in time.

    You need to set stdout and/or stderr to subprocess.PIPE in Popen, otherwise
    the output will be None.

    The returncode is 999 if the process was killed.

    :returns: (returncode, stdout string, stderr string)
    """
    output = []

    def target():
        output.extend(proc.communicate(input))

    thread = threading.Thread(target=target)
    thread.daemon = True
    thread.start()

    killed = False

    thread.join(timeout)
    if thread.is_alive():
        proc.terminate()
        killed = True
        thread.join()

    returncode = proc.returncode
    if killed:
        returncode = 999
    return returncode, output[0], output[1]