@@ -1102,6 +1102,14 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
1102
1102
}
1103
1103
}
1104
1104
1105
+ if (config.preExecDelegate ! is null )
1106
+ {
1107
+ if (config.preExecDelegate() != true )
1108
+ {
1109
+ abortOnError(forkPipeOut, InternalError.preExec, .errno);
1110
+ }
1111
+ }
1112
+
1105
1113
// Execute program.
1106
1114
core.sys.posix.unistd.execve (argz[0 ], argz.ptr, envz);
1107
1115
@@ -1187,7 +1195,7 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
1187
1195
errorMsg = " Failed to allocate memory" ;
1188
1196
break ;
1189
1197
case InternalError.preExec:
1190
- errorMsg = " Failed to execute preExecFunction" ;
1198
+ errorMsg = " Failed to execute preExecFunction or preExecDelegate " ;
1191
1199
break ;
1192
1200
case InternalError.noerror:
1193
1201
assert (false );
@@ -1271,6 +1279,29 @@ version (Posix)
1271
1279
assert (received);
1272
1280
}
1273
1281
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
+
1274
1305
/*
1275
1306
Implementation of spawnProcess() for Windows.
1276
1307
@@ -2186,13 +2217,30 @@ struct Config
2186
2217
Please note that the code in this function must only use
2187
2218
async-signal-safe functions.)
2188
2219
2220
+ If $(LREF preExecDelegate) is also set, it is called last.
2221
+
2189
2222
On Windows, this member is not available.
2190
2223
*/
2191
2224
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;
2192
2239
}
2193
2240
else version (Posix )
2194
2241
{
2195
2242
bool function () nothrow @nogc @safe preExecFunction;
2243
+ bool delegate () nothrow @nogc @safe preExecDelegate;
2196
2244
}
2197
2245
}
2198
2246
0 commit comments