Skip to content

Commit 499c521

Browse files
committed
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).
1 parent 160b619 commit 499c521

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

judge/runguard.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
#include <libcgroup.h>
6363
#include <sched.h>
6464
#include <sys/sysinfo.h>
65+
#include <vector>
66+
#include <string>
6567

6668
#define PROGRAM "runguard"
6769
#define VERSION DOMJUDGE_VERSION "/" REVISION
@@ -106,7 +108,7 @@ char *rootchdir;
106108
char *stdoutfilename;
107109
char *stderrfilename;
108110
char *metafilename;
109-
char *environment_variables;
111+
std::vector<std::string> environment_variables;
110112
FILE *metafile;
111113

112114
char cgroupname[255];
@@ -363,7 +365,8 @@ Run COMMAND with restrictions.\n\
363365
-s, --streamsize=SIZE truncate COMMAND stdout/stderr streams at SIZE kB\n\
364366
-E, --environment preserve environment variables (default only PATH)\n\
365367
-V, --variable add additional environment variables\n\
366-
(in form KEY=VALUE;KEY2=VALUE2)\n\
368+
(in form KEY=VALUE;KEY2=VALUE2); may be passed\n\
369+
multiple times\n\
367370
-M, --outmeta=FILE write metadata (runtime, exitcode, etc.) to FILE\n\
368371
-U, --runpipepid=PID process ID of runpipe to send SIGUSR1 signal when\n\
369372
timelimit is reached\n");
@@ -802,8 +805,8 @@ void setrestrictions()
802805
}
803806

804807
/* Set additional environment variables. */
805-
if (environment_variables != nullptr) {
806-
char *token = strtok(environment_variables, ";");
808+
for (const auto &tokens : environment_variables) {
809+
char *token = strtok(strdup(tokens.c_str()), ";");
807810
while (token != nullptr) {
808811
verbose("setting environment variable: %s", token);
809812
putenv(token);
@@ -1175,7 +1178,7 @@ int main(int argc, char **argv)
11751178
preserve_environment = 1;
11761179
break;
11771180
case 'V': /* set environment variable */
1178-
environment_variables = strdup(optarg);
1181+
environment_variables.push_back(std::string(optarg));
11791182
break;
11801183
case 'M': /* outputmeta option */
11811184
outputmeta = 1;

judge/runguard_test/runguard_test.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,11 @@ test_envvars() {
213213
expect_stdout "USER="
214214
expect_stdout "SHELL="
215215

216-
exec_check_success sudo $RUNGUARD -u domjudge-run-0 -V"DOMjudgeA=A;DOMjudgeB=BB" ./print_envvars.py
217-
expect_stdout "COUNT: 4."
216+
exec_check_success sudo $RUNGUARD -u domjudge-run-0 -V"DOMjudgeA=A;DOMjudgeB=BB" -V"DOMjudgeC=CCC" ./print_envvars.py
217+
expect_stdout "COUNT: 5."
218218
expect_stdout "DOMjudgeA=A"
219219
expect_stdout "DOMjudgeB=BB"
220+
expect_stdout "DOMjudgeC=CCC"
220221
not_expect_stdout "HOME="
221222
not_expect_stdout "USER="
222223
not_expect_stdout "SHELL="

0 commit comments

Comments
 (0)