-
-
Notifications
You must be signed in to change notification settings - Fork 606
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8121 from marler8997/sameEnv
fix Issue 18729 - dmd -run executes in different environment
- Loading branch information
Showing
7 changed files
with
128 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
module dmd.env; | ||
|
||
import core.stdc.string; | ||
import core.sys.posix.stdlib; | ||
import dmd.globals; | ||
import dmd.root.array; | ||
import dmd.root.rmem; | ||
import dmd.utils; | ||
|
||
version (Windows) | ||
private extern (C) int putenv(const char*) nothrow; | ||
|
||
/** | ||
Construct a variable from `name` and `value` and put it in the environment while saving | ||
the previous value of the environment variable into a global list so it can be restored later. | ||
Params: | ||
name = the name of the variable | ||
value = the value of the variable | ||
Returns: | ||
true on error, false on success | ||
*/ | ||
bool putenvRestorable(const(char)[] name, const(char)[] value) nothrow | ||
{ | ||
saveEnvVar(name); | ||
const nameValue = allocNameValue(name, value); | ||
const result = putenv(cast(char*)nameValue.ptr); | ||
version (Windows) | ||
mem.xfree(cast(void*)nameValue.ptr); | ||
else | ||
{ | ||
if (result) | ||
mem.xfree(cast(void*)nameValue.ptr); | ||
} | ||
return result ? true : false; | ||
} | ||
|
||
/** | ||
Allocate a new variable via xmalloc that can be added to the global environment. The | ||
resulting string will be null-terminated immediately after the end of the array. | ||
Params: | ||
name = name of the variable | ||
value = value of the variable | ||
Returns: | ||
a newly allocated variable that can be added to the global environment | ||
*/ | ||
string allocNameValue(const(char)[] name, const(char)[] value) nothrow | ||
{ | ||
const length = name.length + 1 + value.length; | ||
auto str = (cast(char*)mem.xmalloc(length + 1))[0 .. length]; | ||
str[0 .. name.length] = name[]; | ||
str[name.length] = '='; | ||
str[name.length + 1 .. length] = value[]; | ||
str.ptr[length] = '\0'; | ||
return cast(string)str; | ||
} | ||
|
||
/// Holds the original values of environment variables when they are overwritten. | ||
private __gshared string[string] envNameValues; | ||
|
||
/// Restore the original environment. | ||
void restoreEnvVars() | ||
{ | ||
foreach (var; envNameValues.values) | ||
{ | ||
if (putenv(cast(char*)var.ptr)) | ||
assert(0); | ||
} | ||
} | ||
|
||
/// Save the environment variable `name` if not saved already. | ||
void saveEnvVar(const(char)[] name) nothrow | ||
{ | ||
if (!(name in envNameValues)) | ||
{ | ||
envNameValues[name.idup] = allocNameValue(name, name.toCStringThen!(n => getenv(n.ptr)).toDString); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import std.array, std.stdio, std.process, std.algorithm; | ||
void main() | ||
{ | ||
foreach (varPair; environment.toAA().byKeyValue.array.sort!"a.key < b.key") | ||
{ | ||
if (varPair.key != "_") | ||
{ | ||
writeln(varPair.key, "=", varPair.value); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import dshell; | ||
void main() | ||
{ | ||
const envFromExe = shellExpand("$OUTPUT_BASE/envFromExe.txt"); | ||
const envFromRun = shellExpand("$OUTPUT_BASE/envFromRun.txt"); | ||
|
||
run("$DMD -m$MODEL -of$OUTPUT_BASE/printenv$EXE $EXTRA_FILES/printenv.d"); | ||
run("$OUTPUT_BASE/printenv$EXE", File(envFromExe, "wb")); | ||
run("$DMD -m$MODEL -run $EXTRA_FILES/printenv.d", File(envFromRun, "wb")); | ||
|
||
const fromExe = readText(envFromExe); | ||
const fromRun = readText(envFromRun); | ||
if (fromExe != fromRun) | ||
{ | ||
writefln("FromExe:"); | ||
writeln("-----------"); | ||
writeln(fromExe); | ||
writefln("FromRun:"); | ||
writeln("-----------"); | ||
writeln(fromRun); | ||
assert(0, "output from exe/run differ"); | ||
} | ||
} |