From 4623e8eebc4a6c577dbb06fa60da75c41b1b437a Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Sat, 28 Sep 2024 16:29:38 -0700 Subject: [PATCH] Restore thread-unsafe fallback for setting the Process working directory Swift still needs to support Amazon Linux 2 until it EoLs in mid-2025. So restore the thread-unsafe fallback for systems with glibc older than version 2.29, which was removed in #4981. --- Sources/Foundation/Process.swift | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index de2f2e43fd..758dd1dfd4 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -925,8 +925,15 @@ open class Process: NSObject, @unchecked Sendable { for fd in addclose.filter({ $0 >= 0 }) { try _throwIfPosixError(_CFPosixSpawnFileActionsAddClose(fileActions, fd)) } + let useFallbackChdir: Bool if let dir = currentDirectoryURL?.path { - try _throwIfPosixError(_CFPosixSpawnFileActionsChdir(fileActions, dir)) + let chdirResult = _CFPosixSpawnFileActionsChdir(fileActions, dir) + useFallbackChdir = chdirResult == ENOSYS + if !useFallbackChdir { + try _throwIfPosixError(chdirResult) + } + } else { + useFallbackChdir = false } #if canImport(Darwin) || os(Android) || os(OpenBSD) @@ -950,6 +957,27 @@ open class Process: NSObject, @unchecked Sendable { } #endif + // Unsafe fallback for systems missing posix_spawn_file_actions_addchdir[_np] + // This includes Glibc versions older than 2.29 such as on Amazon Linux 2 + let previousDirectoryPath: String? + if useFallbackChdir { + let fileManager = FileManager() + previousDirectoryPath = fileManager.currentDirectoryPath + if let dir = currentDirectoryURL?.path, !fileManager.changeCurrentDirectoryPath(dir) { + throw _NSErrorWithErrno(errno, reading: true, url: currentDirectoryURL) + } + } else { + previousDirectoryPath = nil + } + + defer { + if let previousDirectoryPath { + // Reset the previous working directory path. + let fileManager = FileManager() + _ = fileManager.changeCurrentDirectoryPath(previousDirectoryPath) + } + } + // Launch var pid = pid_t()