Skip to content

Commit 5ce5344

Browse files
author
chloekek
committed
Promote std.process.Config.preExecFunction to a delegate
std.process.Config.preExecFunction is now a delegate instead of a function pointer, and can therefore capture an environment, for example: import core.sys.linux.sys.prctl : PR_SET_PDEATHSIG, prctl; import std.process : Config, execute; void runProgram(int pdeathsig) { execute( ["program"], config: Config( preExecFunction: () @trusted => prctl(PR_SET_PDEATHSIG, pdeathsig, 0, 0, 0) != -1, ), ); } Despite function pointers implicitly converting to delegates, this is a backwards-incompatible change, as user code may rely on the field being a function pointer. For example, code like the following will no longer compile: import std.process : Config; nothrow pure @nogc @safe bool f() { return true; } void example() { auto config = Config(preExecFunction: &f); bool function() g = config.preExecFunction; }
1 parent 4b2ea30 commit 5ce5344

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Promote `std.process.Config.preExecFunction` to a delegate
2+
3+
$(LINK2 $(ROOT_DIR)phobos/std_process.html#.Config.preExecFunction,
4+
`std.process.Config.preExecFunction`) is now a delegate instead of a function
5+
pointer, and can therefore capture an environment, for example:
6+
7+
-------
8+
import core.sys.linux.sys.prctl : PR_SET_PDEATHSIG, prctl;
9+
import std.process : Config, execute;
10+
11+
void runProgram(int pdeathsig)
12+
{
13+
execute(
14+
["program"],
15+
config: Config(
16+
preExecFunction: () @trusted =>
17+
prctl(PR_SET_PDEATHSIG, pdeathsig, 0, 0, 0) != -1,
18+
),
19+
);
20+
}
21+
-------
22+
23+
Despite function pointers implicitly converting to delegates, this is a
24+
backwards-incompatible change, as user code may rely on the field being a
25+
function pointer. For example, code like the following will no longer compile:
26+
27+
-------
28+
import std.process : Config;
29+
30+
nothrow pure @nogc @safe
31+
bool f() { return true; }
32+
33+
void example()
34+
{
35+
auto config = Config(preExecFunction: &f);
36+
bool function() g = config.preExecFunction;
37+
}
38+
-------

std/process.d

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,22 @@ version (Posix)
12711271
assert(received);
12721272
}
12731273

1274+
version (Posix)
1275+
@safe unittest
1276+
{
1277+
foreach (i; 0 .. 3)
1278+
{
1279+
auto config = Config(
1280+
preExecFunction: delegate() @trusted {
1281+
_Exit(i);
1282+
return true;
1283+
},
1284+
);
1285+
auto pid = spawnProcess(["false"], config: config);
1286+
assert(wait(pid) == i);
1287+
}
1288+
}
1289+
12741290
/*
12751291
Implementation of spawnProcess() for Windows.
12761292
@@ -2188,11 +2204,11 @@ struct Config
21882204
21892205
On Windows, this member is not available.
21902206
*/
2191-
bool function() nothrow @nogc @safe preExecFunction;
2207+
bool delegate() nothrow @nogc @safe preExecFunction;
21922208
}
21932209
else version (Posix)
21942210
{
2195-
bool function() nothrow @nogc @safe preExecFunction;
2211+
bool delegate() nothrow @nogc @safe preExecFunction;
21962212
}
21972213
}
21982214

0 commit comments

Comments
 (0)