Keep environment in shell subprocesses

Currently we replace the environment of subprocesses with our own,
primarily only consisting of METER_* entries. Besides clearing
some very useful system dependent variables (like PATH, LDPATH, etc.)
with also prevent the user from passing environment variables to
invoked commands.

This patch will now copy the current environment and extends it with
the variables we want to set.

Signed-off-by: Christian Speich <christian@spei.ch>
pull/601/head
Christian Speich 2022-09-04 10:20:11 +02:00
rodzic e02c985821
commit 445aca6227
3 zmienionych plików z 68 dodań i 27 usunięć

Wyświetl plik

@ -26,6 +26,39 @@
#include <sys/wait.h>
#include <unistd.h>
// Posix says that this variable just exists.
// (On some systems this is also declared in unistd.h)
extern char **environ;
// Not the result borrows memory from env and thus it's lifetime.
vector<const char*> prepareEnv(vector<string>& envs)
{
map<string, const char*> env_map;
int i;
for (i = 0; environ[i]; i++) {
string e = environ[i];
vector<string> parts = splitString(e, '=');
env_map[parts[0]] = environ[i];
}
for (auto &e : envs) {
vector<string> parts = splitString(e, '=');
env_map[parts[0]] = e.c_str();
debug("(shell) env \"%s\"\n", e.c_str());
}
vector<const char*> env(env_map.size()+1);
i = 0;
for (auto &e : env_map) {
env[i] = e.second;
i++;
}
env[i] = NULL;
return env;
}
void invokeShell(string program, vector<string> args, vector<string> envs)
{
vector<const char*> argv(args.size()+2);
@ -41,15 +74,7 @@ void invokeShell(string program, vector<string> args, vector<string> envs)
}
argv[i] = NULL;
vector<const char*> env(envs.size()+1);
env[0] = p;
i = 0;
for (auto &e : envs) {
env[i] = e.c_str();
i++;
debug("(shell) env \"%s\"\n", e.c_str());
}
env[i] = NULL;
vector<const char*> env = prepareEnv(envs);
pid_t pid = fork();
int status;
@ -99,15 +124,7 @@ bool invokeBackgroundShell(string program, vector<string> args, vector<string> e
}
argv[i] = NULL;
vector<const char*> env(envs.size()+1);
env[0] = p;
i = 0;
for (auto &e : envs) {
env[i] = e.c_str();
i++;
debug("(bgshell) env \"%s\"\n", e.c_str());
}
env[i] = NULL;
vector<const char*> env = prepareEnv(envs);
if (pipe(link) == -1) {
error("(bgshell) could not create pipe!\n");
@ -241,15 +258,7 @@ int invokeShellCaptureOutput(string program, vector<string> args, vector<string>
}
argv[i] = NULL;
vector<const char*> env(envs.size()+1);
env[0] = p;
i = 0;
for (auto &e : envs) {
env[i] = e.c_str();
i++;
debug("(shell) env \"%s\"\n", e.c_str());
}
env[i] = NULL;
vector<const char*> env = prepareEnv(envs);
if (pipe(link) == -1) {
error("(shell) could not create pipe!\n");

Wyświetl plik

@ -57,6 +57,9 @@ if [ "$?" != "0" ]; then RC="1"; fi
tests/test_shell2.sh $PROG
if [ "$?" != "0" ]; then RC="1"; fi
tests/test_shell_env.sh $PROG
if [ "$?" != "0" ]; then RC="1"; fi
tests/test_meterfiles.sh $PROG
if [ "$?" != "0" ]; then RC="1"; fi

Wyświetl plik

@ -0,0 +1,29 @@
#!/bin/sh
PROG="$1"
mkdir -p testoutput
TEST=testoutput
TESTNAME="Test shell environment"
TESTRESULT="ERROR"
export MY_ENV_TEST="hello world"
$PROG --shell='echo MY_ENV_TEST="$MY_ENV_TEST"' simulations/simulation_shell.txt MWW supercom587 12345678 "" > $TEST/test_output.txt 2> $TEST/test_stderr.txt
if [ "$?" = "0" ]
then
echo 'MY_ENV_TEST=hello world' > $TEST/test_expected.txt
diff $TEST/test_expected.txt $TEST/test_output.txt
if [ "$?" = "0" ]
then
echo OK: $TESTNAME
TESTRESULT="OK"
fi
fi
if [ "$TESTRESULT" = "ERROR" ]
then
echo ERROR: $TESTNAME
exit 1
fi