diff --git a/changelog/std.process.Config.preExecFunction-delegate.dd b/changelog/std.process.Config.preExecFunction-delegate.dd new file mode 100644 index 00000000000..e9b13b3c268 --- /dev/null +++ b/changelog/std.process.Config.preExecFunction-delegate.dd @@ -0,0 +1,38 @@ +Promote `std.process.Config.preExecFunction` to a delegate + +$(LINK2 $(ROOT_DIR)phobos/std_process.html#.Config.preExecFunction, +`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; +} +------- diff --git a/std/process.d b/std/process.d index 494910f3535..fbdb2e48ea9 100644 --- a/std/process.d +++ b/std/process.d @@ -1271,6 +1271,22 @@ version (Posix) assert(received); } +version (Posix) +@safe unittest +{ + foreach (i; 0 .. 3) + { + auto config = Config( + preExecFunction: delegate() @trusted { + _Exit(i); + return true; + }, + ); + auto pid = spawnProcess(["false"], config: config); + assert(wait(pid) == i); + } +} + /* Implementation of spawnProcess() for Windows. @@ -2188,11 +2204,11 @@ struct Config On Windows, this member is not available. */ - bool function() nothrow @nogc @safe preExecFunction; + bool delegate() nothrow @nogc @safe preExecFunction; } else version (Posix) { - bool function() nothrow @nogc @safe preExecFunction; + bool delegate() nothrow @nogc @safe preExecFunction; } }