From affe6f1dcb8c3b11f7654007a3067831ca0be57c Mon Sep 17 00:00:00 2001 From: tkwiatkowski Date: Wed, 12 Feb 2025 11:50:35 +0100 Subject: [PATCH] Fix bug in interactrive --- src/sinol_make/__init__.py | 2 +- src/sinol_make/executors/sio2jail.py | 26 ++++++++++++------------- src/sinol_make/task_type/interactive.py | 7 ++++--- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/sinol_make/__init__.py b/src/sinol_make/__init__.py index 546deded..ffa53349 100644 --- a/src/sinol_make/__init__.py +++ b/src/sinol_make/__init__.py @@ -12,7 +12,7 @@ from sinol_make.task_type.interactive import InteractiveTaskType # noqa -__version__ = "1.9.6" +__version__ = "1.9.7" def configure_parsers(): diff --git a/src/sinol_make/executors/sio2jail.py b/src/sinol_make/executors/sio2jail.py index 2744f3df..c0bbdb5c 100644 --- a/src/sinol_make/executors/sio2jail.py +++ b/src/sinol_make/executors/sio2jail.py @@ -17,11 +17,12 @@ def __init__(self, sio2jail_path): def _wrap_command(self, command: List[str], result_file_path: str, time_limit: int, memory_limit: int) -> List[str]: # see: https://github.com/sio2project/sioworkers/blob/738aa7a4e93216b0900ca128d6d48d40cd38bc1e/sio/workers/executors.py#L608 - return [f'"{self.sio2jail_path}"', '--mount-namespace', 'off', '--pid-namespace', 'off', '--uts-namespace', + return [f'"{self.sio2jail_path}"', '-f', '3', '--mount-namespace', 'off', '--pid-namespace', 'off', '--uts-namespace', 'off', '--ipc-namespace', 'off', '--net-namespace', 'off', '--capability-drop', 'off', '--user-namespace', 'off', '--instruction-count-limit', f'{int(2 * time_limit)}M', '--rtimelimit', f'{int(16 * time_limit + 1000)}ms', '--memory-limit', f'{int(memory_limit)}K', - '--output-limit', '51200K', '--output', 'oiaug', '--stderr', '--'] + command + '--output-limit', '51200K', '--output', 'oiaug', '--stderr', '--'] + command + \ + ['3>', f'"{result_file_path}"'] def _execute(self, cmdline: str, time_limit: int, hard_time_limit: int, memory_limit: int, result_file_path: str, executable: str, execution_dir: str, stdin: int, stdout: int, @@ -29,17 +30,16 @@ def _execute(self, cmdline: str, time_limit: int, hard_time_limit: int, memory_l *args, **kwargs) -> Tuple[bool, bool, int, List[str]]: env = os.environ.copy() env['UNDER_SIO2JAIL'] = "1" - with open(result_file_path, "w") as result_file: - try: - process = subprocess.Popen(cmdline, *args, shell=True, stdin=stdin, stdout=stdout, env=env, - stderr=result_file, preexec_fn=os.setpgrp, cwd=execution_dir, **kwargs) - except TypeError as e: - print(util.error(f"Invalid command: `{cmdline}`")) - raise e - if fds_to_close is not None: - for fd in fds_to_close: - os.close(fd) - process.wait() + try: + process = subprocess.Popen(cmdline, *args, shell=True, stdin=stdin, stdout=stdout, env=env, + stderr=subprocess.DEVNULL, preexec_fn=os.setpgrp, cwd=execution_dir, **kwargs) + except TypeError as e: + print(util.error(f"Invalid command: `{cmdline}`")) + raise e + if fds_to_close is not None: + for fd in fds_to_close: + os.close(fd) + process.wait() return False, False, 0, [] diff --git a/src/sinol_make/task_type/interactive.py b/src/sinol_make/task_type/interactive.py index 4a5008b9..5e746cd1 100644 --- a/src/sinol_make/task_type/interactive.py +++ b/src/sinol_make/task_type/interactive.py @@ -105,12 +105,15 @@ def _fill_result(self, result: ExecutionResult, iresult: ExecutionResult, intera sol_sig = result.ExitSignal inter_sig = iresult.ExitSignal - if interactor_output[0] != '': + if result.Status is not None and result.Status != Status.OK and sol_sig != signal.SIGPIPE: + return + elif interactor_output[0] != '': if sol_sig == signal.SIGPIPE: result.Status = Status.WA if interactor_output[1]: result.Comment = interactor_output[1] result.Points = 0 + result.Error = None else: try: ok, points, comment = self._parse_checker_output(interactor_output) @@ -133,8 +136,6 @@ def _fill_result(self, result: ExecutionResult, iresult: ExecutionResult, intera f"Interactor stderr: {iresult.Stderr}. " f"Interactor output: {interactor_output}") result.Fail = True - elif result.Status is not None and result.Status != Status.OK and sol_sig != signal.SIGPIPE: - return elif inter_sig == signal.SIGPIPE: result.Status = Status.WA result.Comment = "Solution exited prematurely"