Skip to content

Commit d767448

Browse files
schveiguydlang-bot
authored andcommitted
Fix #10574 - environment pointer sometimes changes before exec, causing
segfault in child process.
1 parent bf6e70b commit d767448

File tree

1 file changed

+7
-16
lines changed

1 file changed

+7
-16
lines changed

std/process.d

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ private
148148
{
149149
version (Darwin)
150150
{
151-
extern(C) char*** _NSGetEnviron() nothrow;
152-
const(char**) getEnvironPtr() @trusted
151+
extern(C) char*** _NSGetEnviron() @nogc nothrow;
152+
const(char**) getEnvironPtr() @trusted @nogc nothrow
153153
{
154154
return *_NSGetEnviron;
155155
}
@@ -158,7 +158,7 @@ private
158158
{
159159
// Made available by the C runtime:
160160
extern(C) extern __gshared const char** environ;
161-
const(char**) getEnvironPtr() @trusted
161+
const(char**) getEnvironPtr() @trusted @nogc nothrow
162162
{
163163
return environ;
164164
}
@@ -1119,7 +1119,7 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
11191119
}
11201120

11211121
// Execute program.
1122-
core.sys.posix.unistd.execve(argz[0], argz.ptr, envz);
1122+
core.sys.posix.unistd.execve(argz[0], argz.ptr, envz is null ? getEnvironPtr : envz);
11231123

11241124
// If execution fails, exit as quickly as possible.
11251125
abortOnError(forkPipeOut, InternalError.exec, .errno);
@@ -1421,7 +1421,7 @@ private Pid spawnProcessWin(scope const(char)[] commandLine,
14211421
// on the form "name=value", optionally adding those of the current process'
14221422
// environment strings that are not present in childEnv. If the parent's
14231423
// environment should be inherited without modification, this function
1424-
// returns environ directly.
1424+
// returns null.
14251425
version (Posix)
14261426
private const(char*)* createEnv(const string[string] childEnv,
14271427
bool mergeWithParentEnv)
@@ -1431,7 +1431,7 @@ private const(char*)* createEnv(const string[string] childEnv,
14311431
auto environ = getEnvironPtr;
14321432
if (mergeWithParentEnv)
14331433
{
1434-
if (childEnv.length == 0) return environ;
1434+
if (childEnv.length == 0) return null;
14351435
while (environ[parentEnvLength] != null) ++parentEnvLength;
14361436
}
14371437

@@ -1461,16 +1461,7 @@ version (Posix) @system unittest
14611461
assert(e1 != null && *e1 == null);
14621462

14631463
auto e2 = createEnv(null, true);
1464-
assert(e2 != null);
1465-
int i = 0;
1466-
auto environ = getEnvironPtr;
1467-
for (; environ[i] != null; ++i)
1468-
{
1469-
assert(e2[i] != null);
1470-
import core.stdc.string : strcmp;
1471-
assert(strcmp(e2[i], environ[i]) == 0);
1472-
}
1473-
assert(e2[i] == null);
1464+
assert(e2 == null);
14741465

14751466
auto e3 = createEnv(["foo" : "bar", "hello" : "world"], false);
14761467
assert(e3 != null && e3[0] != null && e3[1] != null && e3[2] == null);

0 commit comments

Comments
 (0)