@@ -319,28 +319,46 @@ public final class Process: ObjectIdentifierProtocol {
319319 _ program: String ,
320320 workingDirectory: AbsolutePath ? = nil
321321 ) -> AbsolutePath ? {
322- return Process . executablesQueue. sync {
323- // Check if we already have a value for the program.
324- if let value = Process . validatedExecutablesMap [ program] {
325- return value
322+ if let abs = try ? AbsolutePath ( validating: program) {
323+ return abs
324+ }
325+ let cwdOpt = workingDirectory ?? localFileSystem. currentWorkingDirectory
326+ // The program might be a multi-component relative path.
327+ if let rel = try ? RelativePath ( validating: program) , rel. components. count > 1 {
328+ if let cwd = cwdOpt {
329+ let abs = cwd. appending ( rel)
330+ if localFileSystem. isExecutableFile ( abs) {
331+ return abs
332+ }
326333 }
327-
328- let cwd = workingDirectory ?? localFileSystem . currentWorkingDirectory
329-
330- // FIXME: This can be cached.
334+ return nil
335+ }
336+ // From here on out, the program is an executable name, i.e. it doesn't contain a "/"
337+ let lookup : ( ) -> AbsolutePath ? = {
331338 let envSearchPaths = getEnvSearchPaths (
332339 pathString: ProcessEnv . path,
333- currentWorkingDirectory: cwd
340+ currentWorkingDirectory: cwdOpt
334341 )
335- // Lookup and cache the executable path.
336342 let value = lookupExecutablePath (
337343 filename: program,
338- currentWorkingDirectory: cwd ,
344+ currentWorkingDirectory: cwdOpt ,
339345 searchPaths: envSearchPaths
340346 )
341- Process . validatedExecutablesMap [ program] = value
342347 return value
343348 }
349+ // This should cover the most common cases, i.e. when the cache is most helpful.
350+ if workingDirectory == localFileSystem. currentWorkingDirectory {
351+ return Process . executablesQueue. sync {
352+ if let value = Process . validatedExecutablesMap [ program] {
353+ return value
354+ }
355+ let value = lookup ( )
356+ Process . validatedExecutablesMap [ program] = value
357+ return value
358+ }
359+ } else {
360+ return lookup ( )
361+ }
344362 }
345363
346364 /// Launch the subprocess.
0 commit comments