kopia lustrzana https://github.com/weetmuts/wmbusmeters
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
rodzic
e02c985821
commit
445aca6227
63
src/shell.cc
63
src/shell.cc
|
@ -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");
|
||||
|
|
3
test.sh
3
test.sh
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
Ładowanie…
Reference in New Issue