@@ -315,20 +315,29 @@ public final class Process: ObjectIdentifierProtocol {
315
315
/// Returns the path of the the given program if found in the search paths.
316
316
///
317
317
/// The program can be executable name, relative path or absolute path.
318
- public static func findExecutable( _ program: String ) -> AbsolutePath ? {
318
+ public static func findExecutable(
319
+ _ program: String ,
320
+ workingDirectory: AbsolutePath ? = nil
321
+ ) -> AbsolutePath ? {
319
322
return Process . executablesQueue. sync {
320
323
// Check if we already have a value for the program.
321
324
if let value = Process . validatedExecutablesMap [ program] {
322
325
return value
323
326
}
327
+
328
+ let cwd = workingDirectory ?? localFileSystem. currentWorkingDirectory
329
+
324
330
// FIXME: This can be cached.
325
331
let envSearchPaths = getEnvSearchPaths (
326
332
pathString: ProcessEnv . path,
327
- currentWorkingDirectory: localFileSystem . currentWorkingDirectory
333
+ currentWorkingDirectory: cwd
328
334
)
329
335
// Lookup and cache the executable path.
330
336
let value = lookupExecutablePath (
331
- filename: program, searchPaths: envSearchPaths)
337
+ filename: program,
338
+ currentWorkingDirectory: cwd,
339
+ searchPaths: envSearchPaths
340
+ )
332
341
Process . validatedExecutablesMap [ program] = value
333
342
return value
334
343
}
@@ -350,7 +359,7 @@ public final class Process: ObjectIdentifierProtocol {
350
359
351
360
// Look for executable.
352
361
let executable = arguments [ 0 ]
353
- guard let executablePath = Process . findExecutable ( executable) else {
362
+ guard let executablePath = Process . findExecutable ( executable, workingDirectory : workingDirectory ) else {
354
363
throw Process . Error. missingExecutableProgram ( program: executable)
355
364
}
356
365
@@ -495,7 +504,11 @@ public final class Process: ObjectIdentifierProtocol {
495
504
posix_spawn_file_actions_adddup2 ( & fileActions, 2 , 2 )
496
505
}
497
506
498
- let argv = CStringArray ( arguments)
507
+ var resolvedArgs = arguments
508
+ if workingDirectory != nil {
509
+ resolvedArgs [ 0 ] = executablePath. pathString
510
+ }
511
+ let argv = CStringArray ( resolvedArgs)
499
512
let env = CStringArray ( environment. map ( { " \( $0. 0 ) = \( $0. 1 ) " } ) )
500
513
let rv = posix_spawnp ( & processID, argv. cArray [ 0 ] !, & fileActions, & attributes, argv. cArray, env. cArray)
501
514
0 commit comments