From e14add5b1fcaa36270b56e08979708633761f845 Mon Sep 17 00:00:00 2001 From: Aberter Yan Date: Wed, 10 Sep 2025 14:09:35 +0800 Subject: [PATCH 1/2] fix: Watcher on MacOS --- src/core/judgingthread.cpp | 4 ++-- unix/watcher_unix.cpp | 33 ++++++++++++--------------------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/core/judgingthread.cpp b/src/core/judgingthread.cpp index b2670d5e..60676b66 100644 --- a/src/core/judgingthread.cpp +++ b/src/core/judgingthread.cpp @@ -954,7 +954,7 @@ void JudgingThread::runProgram() { } argumentsList << "_tmperr"; - argumentsList << QString("%1").arg(timeLimit + extraTime); + argumentsList << QString("%1").arg(timeLimit); argumentsList << QString("%1").arg(memoryLimit); argumentsList << QString("%1").arg(rawTimeLimit); argumentsList << QString("%1").arg(rawMemoryLimit); @@ -1007,7 +1007,7 @@ void JudgingThread::runProgram() { } argumentsList << "_tmperr"; - argumentsList << QString("%1").arg(timeLimit + extraTime); + argumentsList << QString("%1").arg(timeLimit); argumentsList << QString("%1").arg(memoryLimit); argumentsList << QString("%1").arg(rawTimeLimit); argumentsList << QString("%1").arg(rawMemoryLimit); diff --git a/unix/watcher_unix.cpp b/unix/watcher_unix.cpp index 6c3192d2..096042e6 100644 --- a/unix/watcher_unix.cpp +++ b/unix/watcher_unix.cpp @@ -144,29 +144,20 @@ auto main(int argc, char *argv[]) -> int { return RS_RE; } } else { - if (! stdinRedirect.empty()) { - if (freopen(stdinRedirect.c_str(), "r", stdin) == NULL) { - perror("freopen stdin"); - exit(RS_FAIL); - } - } else { - fclose(stdin); + std::string finalStdinRedirect = stdinRedirect.empty() ? "/dev/null" : stdinRedirect; + if (freopen(finalStdinRedirect.c_str(), "r", stdin) == NULL) { + perror("freopen stdin"); + exit(RS_FAIL); } - if (! stdoutRedirect.empty()) { - if (freopen(stdoutRedirect.c_str(), "w", stdout) == NULL) { - perror("freopen stdout"); - exit(RS_FAIL); - } - } else { - fclose(stdout); + std::string finalStdoutRedirect = stdoutRedirect.empty() ? "/dev/null" : stdoutRedirect; + if (freopen(finalStdoutRedirect.c_str(), "w", stdout) == NULL) { + perror("freopen stdout"); + exit(RS_FAIL); } - if (! stderrRedirect.empty()) { - if (freopen(stderrRedirect.c_str(), "w", stderr) == NULL) { - perror("freopen stderr"); - exit(RS_FAIL); - } - } else { - fclose(stderr); + std::string finalStderrRedirect = stderrRedirect.empty() ? "/dev/null" : stderrRedirect; + if (freopen(finalStderrRedirect.c_str(), "w", stderr) == NULL) { + perror("freopen stderr"); + exit(RS_FAIL); } rlimit memlim{}, stalim{}, timlim{}; From 4e6c77fbd17195f124f2a17efd8db2205680e149 Mon Sep 17 00:00:00 2001 From: Aberter Yan Date: Wed, 10 Sep 2025 14:32:17 +0800 Subject: [PATCH 2/2] fix: Kill time limit for watcher --- src/core/judgingthread.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/judgingthread.cpp b/src/core/judgingthread.cpp index 60676b66..b85a59fa 100644 --- a/src/core/judgingthread.cpp +++ b/src/core/judgingthread.cpp @@ -1044,7 +1044,10 @@ void JudgingThread::runProgram() { QElapsedTimer timer; timer.start(); - while (timer.elapsed() <= timeLimit + extraTime) { + // Using rlimit to limit CPU time can only be accurate to seconds, + // so here it is rounded up to an integer second. + long long killTimeLimit = (timeLimit + 999) / 1000 * 1000 + extraTime; + while (timer.elapsed() <= killTimeLimit) { if (runner->state() != QProcess::Running) { isProgramFinishedInExtraTimeLimit = true; break;