From 22de6358e685f736c7adb96dbe14cbec4f9a71d6 Mon Sep 17 00:00:00 2001 From: Wouter Wijsman Date: Sun, 8 Dec 2024 13:18:05 +0100 Subject: [PATCH] Fix _exe_cmd in installer.py (#2) * Fix _exe_cmd in installer.py * Only print if print_output is on * Set stdout and stderr to non-blocking in exe_cmd function --- minigalaxy/installer.py | 54 +++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/minigalaxy/installer.py b/minigalaxy/installer.py index 5f642fdd..f259ca18 100644 --- a/minigalaxy/installer.py +++ b/minigalaxy/installer.py @@ -5,6 +5,7 @@ import subprocess import hashlib import textwrap +import time from minigalaxy.config import Config from minigalaxy.game import Game @@ -237,7 +238,7 @@ def extract_by_wine(game, installer, temp_dir, config=Config()): def try_wine_command(command_arr): print('trying to run wine command:', shlex.join(command_arr)) - stdout, stderr, exitcode = _exe_cmd(command_arr, False, True) + stdout, stderr, exitcode = _exe_cmd(command_arr, True) print(stdout) if exitcode not in [0]: print(stderr, file=sys.stderr) @@ -374,34 +375,35 @@ def uninstall_game(game): os.remove(path_to_shortcut) -def _exe_cmd(cmd, capture_output=True, print_output=False): - """Wine commands are very verbose. - We should consume the output in regularly to prevent buffers (and minigalaxy memory) from filling up""" - print(f'executing wine command: {shlex.join(cmd)}') - std_out = [] - process = subprocess.Popen(cmd, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - bufsize=1, universal_newlines=True, encoding="utf-8") - rc = process.poll() - while rc is None: - out_line = process.stdout.readline() - if capture_output and out_line != '': - std_out.append(out_line) - - if print_output: - print(out_line, end='') - - rc = process.poll() - - print('command finished, read remaining output (if any)') - for line in process.stdout.readlines(): - std_out.append(line) - print('done') +def _exe_cmd(cmd, print_output=False): + std_out = "" + std_err = "" + done = False + return_code = None + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + universal_newlines=True, encoding="utf-8" + ) + os.set_blocking(process.stdout.fileno(), False) + os.set_blocking(process.stderr.fileno(), False) + while not done: + if (return_code := process.poll()) is not None: + done = True + if data := process.stdout.readline(): + std_out += data + if print_output: + print(data, end='') + if data := process.stderr.readline(): + std_err += data + if print_output: + print(data, end='') + time.sleep(0.01) process.stdout.close() + process.stderr.close() - output = ''.join(std_out) - return output, output, rc + return std_out, std_err, return_code def _mv(source_dir, target_dir):