aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std/process.d
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src/std/process.d')
-rw-r--r--libphobos/src/std/process.d50
1 files changed, 49 insertions, 1 deletions
diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d
index 494910f..325689b 100644
--- a/libphobos/src/std/process.d
+++ b/libphobos/src/std/process.d
@@ -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.
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";
break;
case InternalError.preExec:
- errorMsg = "Failed to execute preExecFunction";
+ errorMsg = "Failed to execute preExecFunction or preExecDelegate";
break;
case InternalError.noerror:
assert(false);
@@ -1271,6 +1279,29 @@ version (Posix)
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.
@@ -2186,13 +2217,30 @@ struct Config
Please note that the code in this function must only use
async-signal-safe functions.)
+ If $(LREF preExecDelegate) is also set, it is called last.
+
On Windows, this member is not available.
*/
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)
{
bool function() nothrow @nogc @safe preExecFunction;
+ bool delegate() nothrow @nogc @safe preExecDelegate;
}
}