mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Merge pull request #8989 from chloekek/std.process.Config.preExecFunction-delegate
Promote `std.process.Config.preExecFunction` to a delegate
This commit is contained in:
commit
8e6f77231a
2 changed files with 74 additions and 1 deletions
25
changelog/std.process.Config.preExecDelegate.dd
Normal file
25
changelog/std.process.Config.preExecDelegate.dd
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Add `std.process.Config.preExecDelegate`
|
||||||
|
|
||||||
|
$(LINK2 $(ROOT_DIR)phobos/std_process.html#.Config.preExecDelegate, `std.process.Config.preExecDelegate`)
|
||||||
|
is just like
|
||||||
|
$(LINK2 $(ROOT_DIR)phobos/std_process.html#.Config.preExecFunction, `std.process.Config.preExecFunction`),
|
||||||
|
but can 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(
|
||||||
|
preExecDelegate: () @trusted =>
|
||||||
|
prctl(PR_SET_PDEATHSIG, pdeathsig, 0, 0, 0) != -1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
-------
|
||||||
|
|
||||||
|
`preExecFunction` is retained for backwards compatibility. If both
|
||||||
|
`preExecFunction` and `preExecDelegate` are given, both are called.
|
|
@ -1102,6 +1102,14 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.preExecDelegate !is null)
|
||||||
|
{
|
||||||
|
if (config.preExecDelegate() != true)
|
||||||
|
{
|
||||||
|
abortOnError(forkPipeOut, InternalError.preExec, .errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Execute program.
|
// Execute program.
|
||||||
core.sys.posix.unistd.execve(argz[0], argz.ptr, envz);
|
core.sys.posix.unistd.execve(argz[0], argz.ptr, envz);
|
||||||
|
|
||||||
|
@ -1187,7 +1195,7 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
|
||||||
errorMsg = "Failed to allocate memory";
|
errorMsg = "Failed to allocate memory";
|
||||||
break;
|
break;
|
||||||
case InternalError.preExec:
|
case InternalError.preExec:
|
||||||
errorMsg = "Failed to execute preExecFunction";
|
errorMsg = "Failed to execute preExecFunction or preExecDelegate";
|
||||||
break;
|
break;
|
||||||
case InternalError.noerror:
|
case InternalError.noerror:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -1271,6 +1279,29 @@ version (Posix)
|
||||||
assert(received);
|
assert(received);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version (Posix)
|
||||||
|
@system unittest
|
||||||
|
{
|
||||||
|
__gshared int j;
|
||||||
|
foreach (i; 0 .. 3)
|
||||||
|
{
|
||||||
|
auto config = Config(
|
||||||
|
preExecFunction: function() @trusted {
|
||||||
|
j = 1;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
preExecDelegate: delegate() @trusted {
|
||||||
|
// j should now be 1, as preExecFunction is called before
|
||||||
|
// preExecDelegate is.
|
||||||
|
_Exit(i + j);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
auto pid = spawnProcess(["false"], config: config);
|
||||||
|
assert(wait(pid) == i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implementation of spawnProcess() for Windows.
|
Implementation of spawnProcess() for Windows.
|
||||||
|
|
||||||
|
@ -2186,13 +2217,30 @@ struct Config
|
||||||
Please note that the code in this function must only use
|
Please note that the code in this function must only use
|
||||||
async-signal-safe functions.)
|
async-signal-safe functions.)
|
||||||
|
|
||||||
|
If $(LREF preExecDelegate) is also set, it is called last.
|
||||||
|
|
||||||
On Windows, this member is not available.
|
On Windows, this member is not available.
|
||||||
*/
|
*/
|
||||||
bool function() nothrow @nogc @safe preExecFunction;
|
bool function() nothrow @nogc @safe preExecFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A delegate that is called before `exec` in $(LREF spawnProcess).
|
||||||
|
It returns `true` if succeeded and otherwise returns `false`.
|
||||||
|
|
||||||
|
$(RED Warning:
|
||||||
|
Please note that the code in this function must only use
|
||||||
|
async-signal-safe functions.)
|
||||||
|
|
||||||
|
If $(LREF preExecFunction) is also set, it is called first.
|
||||||
|
|
||||||
|
On Windows, this member is not available.
|
||||||
|
*/
|
||||||
|
bool delegate() nothrow @nogc @safe preExecDelegate;
|
||||||
}
|
}
|
||||||
else version (Posix)
|
else version (Posix)
|
||||||
{
|
{
|
||||||
bool function() nothrow @nogc @safe preExecFunction;
|
bool function() nothrow @nogc @safe preExecFunction;
|
||||||
|
bool delegate() nothrow @nogc @safe preExecDelegate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue