@@ -1102,6 +1102,14 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
11021102 }
11031103 }
11041104
1105+ if (config.preExecDelegate ! is null )
1106+ {
1107+ if (config.preExecDelegate() != true )
1108+ {
1109+ abortOnError(forkPipeOut, InternalError.preExec, .errno);
1110+ }
1111+ }
1112+
11051113 // Execute program.
11061114 core.sys.posix.unistd.execve (argz[0 ], argz.ptr, envz);
11071115
@@ -1187,7 +1195,7 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
11871195 errorMsg = " Failed to allocate memory" ;
11881196 break ;
11891197 case InternalError.preExec:
1190- errorMsg = " Failed to execute preExecFunction" ;
1198+ errorMsg = " Failed to execute preExecFunction or preExecDelegate " ;
11911199 break ;
11921200 case InternalError.noerror:
11931201 assert (false );
@@ -1271,6 +1279,29 @@ version (Posix)
12711279 assert (received);
12721280}
12731281
1282+ version (Posix )
1283+ @system unittest
1284+ {
1285+ __gshared int j;
1286+ foreach (i; 0 .. 3 )
1287+ {
1288+ auto config = Config(
1289+ preExecFunction: function () @trusted {
1290+ j = 1 ;
1291+ return true ;
1292+ },
1293+ preExecDelegate: delegate () @trusted {
1294+ // j should now be 1, as preExecFunction is called before
1295+ // preExecDelegate is.
1296+ _Exit(i + j);
1297+ return true ;
1298+ },
1299+ );
1300+ auto pid = spawnProcess([" false" ], config: config);
1301+ assert (wait(pid) == i + 1 );
1302+ }
1303+ }
1304+
12741305/*
12751306Implementation of spawnProcess() for Windows.
12761307
@@ -2186,13 +2217,30 @@ struct Config
21862217 Please note that the code in this function must only use
21872218 async-signal-safe functions.)
21882219
2220+ If $(LREF preExecDelegate) is also set, it is called last.
2221+
21892222 On Windows, this member is not available.
21902223 */
21912224 bool function () nothrow @nogc @safe preExecFunction;
2225+
2226+ /**
2227+ A delegate that is called before `exec` in $(LREF spawnProcess).
2228+ It returns `true` if succeeded and otherwise returns `false`.
2229+
2230+ $(RED Warning:
2231+ Please note that the code in this function must only use
2232+ async-signal-safe functions.)
2233+
2234+ If $(LREF preExecFunction) is also set, it is called first.
2235+
2236+ On Windows, this member is not available.
2237+ */
2238+ bool delegate () nothrow @nogc @safe preExecDelegate;
21922239 }
21932240 else version (Posix )
21942241 {
21952242 bool function () nothrow @nogc @safe preExecFunction;
2243+ bool delegate () nothrow @nogc @safe preExecDelegate;
21962244 }
21972245}
21982246
0 commit comments