From d9d9d72a2833de29b2e6bade84d63beb43aea558 Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Sun, 17 Nov 2024 11:02:33 +0100 Subject: [PATCH] runguard: Allow passing `-V` multiple times. The previous behavior was that the last arg wins. IMHO, this is confusing and we even fell into this trap ourselves in https://github.com/DOMjudge/domjudge/blame/main/judge/compile.sh#L145 where we would shadow any previously passed env var (such as the entry point). --- judge/runguard.cc | 13 ++++++++----- judge/runguard_test/runguard_test.sh | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/judge/runguard.cc b/judge/runguard.cc index 81f3b28f22..55aebe9283 100644 --- a/judge/runguard.cc +++ b/judge/runguard.cc @@ -62,6 +62,8 @@ #include #include #include +#include +#include #define PROGRAM "runguard" #define VERSION DOMJUDGE_VERSION "/" REVISION @@ -106,7 +108,7 @@ char *rootchdir; char *stdoutfilename; char *stderrfilename; char *metafilename; -char *environment_variables; +std::vector environment_variables; FILE *metafile; char cgroupname[255]; @@ -363,7 +365,8 @@ Run COMMAND with restrictions.\n\ -s, --streamsize=SIZE truncate COMMAND stdout/stderr streams at SIZE kB\n\ -E, --environment preserve environment variables (default only PATH)\n\ -V, --variable add additional environment variables\n\ - (in form KEY=VALUE;KEY2=VALUE2)\n\ + (in form KEY=VALUE;KEY2=VALUE2); may be passed\n\ + multiple times\n\ -M, --outmeta=FILE write metadata (runtime, exitcode, etc.) to FILE\n\ -U, --runpipepid=PID process ID of runpipe to send SIGUSR1 signal when\n\ timelimit is reached\n"); @@ -802,8 +805,8 @@ void setrestrictions() } /* Set additional environment variables. */ - if (environment_variables != nullptr) { - char *token = strtok(environment_variables, ";"); + for (const auto &tokens : environment_variables) { + char *token = strtok(strdup(tokens.c_str()), ";"); while (token != nullptr) { verbose("setting environment variable: %s", token); putenv(token); @@ -1175,7 +1178,7 @@ int main(int argc, char **argv) preserve_environment = 1; break; case 'V': /* set environment variable */ - environment_variables = strdup(optarg); + environment_variables.push_back(std::string(optarg)); break; case 'M': /* outputmeta option */ outputmeta = 1; diff --git a/judge/runguard_test/runguard_test.sh b/judge/runguard_test/runguard_test.sh index e6434f93f1..a8428ad4b4 100755 --- a/judge/runguard_test/runguard_test.sh +++ b/judge/runguard_test/runguard_test.sh @@ -213,10 +213,11 @@ test_envvars() { expect_stdout "USER=" expect_stdout "SHELL=" - exec_check_success sudo $RUNGUARD -u domjudge-run-0 -V"DOMjudgeA=A;DOMjudgeB=BB" ./print_envvars.py - expect_stdout "COUNT: 4." + exec_check_success sudo $RUNGUARD -u domjudge-run-0 -V"DOMjudgeA=A;DOMjudgeB=BB" -V"DOMjudgeC=CCC" ./print_envvars.py + expect_stdout "COUNT: 5." expect_stdout "DOMjudgeA=A" expect_stdout "DOMjudgeB=BB" + expect_stdout "DOMjudgeC=CCC" not_expect_stdout "HOME=" not_expect_stdout "USER=" not_expect_stdout "SHELL="