From 0c7b84acc9339e0d04844e24479a82b4a5c54219 Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Mon, 16 Jun 2025 15:59:34 -0700 Subject: [PATCH 1/2] Revert "Use `posix_spawn_file_actions_adddup2()` to clear `FD_CLOEXEC`. (#1147)" This reverts commit 32782178a6a210e1eb399ed9cac3c6efc581cba3. --- Sources/Testing/ExitTests/ExitTest.swift | 9 ++ Sources/Testing/ExitTests/SpawnProcess.swift | 50 +++------ Sources/Testing/Support/FileHandle.swift | 110 +++++++++++++------ Sources/Testing/Support/Versions.swift | 24 ---- Sources/_TestingInternals/include/Includes.h | 4 - 5 files changed, 98 insertions(+), 99 deletions(-) diff --git a/Sources/Testing/ExitTests/ExitTest.swift b/Sources/Testing/ExitTests/ExitTest.swift index c5579981e..c114117eb 100644 --- a/Sources/Testing/ExitTests/ExitTest.swift +++ b/Sources/Testing/ExitTests/ExitTest.swift @@ -824,6 +824,15 @@ extension ExitTest { childEnvironment["SWT_EXPERIMENTAL_CAPTURED_VALUES"] = capturedValuesEnvironmentVariable } +#if !SWT_TARGET_OS_APPLE + // Set inherited those file handles that the child process needs. On + // Darwin, this is a no-op because we use POSIX_SPAWN_CLOEXEC_DEFAULT. + try stdoutWriteEnd?.setInherited(true) + try stderrWriteEnd?.setInherited(true) + try backChannelWriteEnd.setInherited(true) + try capturedValuesReadEnd.setInherited(true) +#endif + // Spawn the child process. let processID = try withUnsafePointer(to: backChannelWriteEnd) { backChannelWriteEnd in try withUnsafePointer(to: capturedValuesReadEnd) { capturedValuesReadEnd in diff --git a/Sources/Testing/ExitTests/SpawnProcess.swift b/Sources/Testing/ExitTests/SpawnProcess.swift index 66143a7e0..c365f33ea 100644 --- a/Sources/Testing/ExitTests/SpawnProcess.swift +++ b/Sources/Testing/ExitTests/SpawnProcess.swift @@ -124,27 +124,11 @@ func spawnExecutable( guard let fd else { throw SystemError(description: "A child process cannot inherit a file handle without an associated file descriptor. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") } - if let standardFD, standardFD != fd { + if let standardFD { _ = posix_spawn_file_actions_adddup2(fileActions, fd, standardFD) } else { #if SWT_TARGET_OS_APPLE _ = posix_spawn_file_actions_addinherit_np(fileActions, fd) -#else - // posix_spawn_file_actions_adddup2() will automatically clear - // FD_CLOEXEC after forking but before execing even if the old and - // new file descriptors are equal. This behavior is supported by - // Glibc ≥ 2.29, FreeBSD, OpenBSD, and Android (Bionic) and is - // standardized in POSIX.1-2024 (see https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_adddup2.html - // and https://www.austingroupbugs.net/view.php?id=411). - _ = posix_spawn_file_actions_adddup2(fileActions, fd, fd) -#if canImport(Glibc) - if _slowPath(glibcVersion.major < 2 || (glibcVersion.major == 2 && glibcVersion.minor < 29)) { - // This system is using an older version of glibc that does not - // implement FD_CLOEXEC clearing in posix_spawn_file_actions_adddup2(), - // so we must clear it here in the parent process. - try setFD_CLOEXEC(false, onFileDescriptor: fd) - } -#endif #endif highestFD = max(highestFD, fd) } @@ -173,6 +157,8 @@ func spawnExecutable( #if !SWT_NO_DYNAMIC_LINKING // This platform doesn't have POSIX_SPAWN_CLOEXEC_DEFAULT, but we can at // least close all file descriptors higher than the highest inherited one. + // We are assuming here that the caller didn't set FD_CLOEXEC on any of + // these file descriptors. _ = _posix_spawn_file_actions_addclosefrom_np?(fileActions, highestFD + 1) #endif #elseif os(FreeBSD) @@ -231,42 +217,36 @@ func spawnExecutable( } #elseif os(Windows) return try _withStartupInfoEx(attributeCount: 1) { startupInfo in - func inherit(_ fileHandle: borrowing FileHandle) throws -> HANDLE? { + func inherit(_ fileHandle: borrowing FileHandle, as outWindowsHANDLE: inout HANDLE?) throws { try fileHandle.withUnsafeWindowsHANDLE { windowsHANDLE in guard let windowsHANDLE else { throw SystemError(description: "A child process cannot inherit a file handle without an associated Windows handle. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") } - - // Ensure the file handle can be inherited by the child process. - guard SetHandleInformation(windowsHANDLE, DWORD(HANDLE_FLAG_INHERIT), DWORD(HANDLE_FLAG_INHERIT)) else { - throw Win32Error(rawValue: GetLastError()) - } - - return windowsHANDLE + outWindowsHANDLE = windowsHANDLE } } - func inherit(_ fileHandle: borrowing FileHandle?) throws -> HANDLE? { + func inherit(_ fileHandle: borrowing FileHandle?, as outWindowsHANDLE: inout HANDLE?) throws { if fileHandle != nil { - return try inherit(fileHandle!) + try inherit(fileHandle!, as: &outWindowsHANDLE) } else { - return nil + outWindowsHANDLE = nil } } // Forward standard I/O streams. - startupInfo.pointee.StartupInfo.hStdInput = try inherit(standardInput) - startupInfo.pointee.StartupInfo.hStdOutput = try inherit(standardOutput) - startupInfo.pointee.StartupInfo.hStdError = try inherit(standardError) + try inherit(standardInput, as: &startupInfo.pointee.StartupInfo.hStdInput) + try inherit(standardOutput, as: &startupInfo.pointee.StartupInfo.hStdOutput) + try inherit(standardError, as: &startupInfo.pointee.StartupInfo.hStdError) startupInfo.pointee.StartupInfo.dwFlags |= STARTF_USESTDHANDLES // Ensure standard I/O streams and any explicitly added file handles are // inherited by the child process. var inheritedHandles = [HANDLE?](repeating: nil, count: additionalFileHandles.count + 3) - inheritedHandles[0] = startupInfo.pointee.StartupInfo.hStdInput - inheritedHandles[1] = startupInfo.pointee.StartupInfo.hStdOutput - inheritedHandles[2] = startupInfo.pointee.StartupInfo.hStdError + try inherit(standardInput, as: &inheritedHandles[0]) + try inherit(standardOutput, as: &inheritedHandles[1]) + try inherit(standardError, as: &inheritedHandles[2]) for i in 0 ..< additionalFileHandles.count { - inheritedHandles[i + 3] = try inherit(additionalFileHandles[i].pointee) + try inherit(additionalFileHandles[i].pointee, as: &inheritedHandles[i + 3]) } inheritedHandles = inheritedHandles.compactMap(\.self) diff --git a/Sources/Testing/Support/FileHandle.swift b/Sources/Testing/Support/FileHandle.swift index 1c5447460..4e3c17372 100644 --- a/Sources/Testing/Support/FileHandle.swift +++ b/Sources/Testing/Support/FileHandle.swift @@ -108,7 +108,8 @@ struct FileHandle: ~Copyable, Sendable { /// /// By default, the resulting file handle is not inherited by any child /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.). + /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call + /// ``setInherited()``. init(forReadingAtPath path: String) throws { try self.init(atPath: path, mode: "reb") } @@ -122,7 +123,8 @@ struct FileHandle: ~Copyable, Sendable { /// /// By default, the resulting file handle is not inherited by any child /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.). + /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call + /// ``setInherited()``. init(forWritingAtPath path: String) throws { try self.init(atPath: path, mode: "web") } @@ -490,7 +492,8 @@ extension FileHandle { /// /// By default, the resulting file handles are not inherited by any child /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.). + /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make them inheritable, + /// call ``setInherited()``. static func makePipe(readEnd: inout FileHandle?, writeEnd: inout FileHandle?) throws { #if !os(Windows) var pipe2Called = false @@ -530,8 +533,8 @@ extension FileHandle { if !pipe2Called { // pipe2() is not available. Use pipe() instead and simulate O_CLOEXEC // to the best of our ability. - try setFD_CLOEXEC(true, onFileDescriptor: fdReadEnd) - try setFD_CLOEXEC(true, onFileDescriptor: fdWriteEnd) + try _setFileDescriptorInherited(fdReadEnd, false) + try _setFileDescriptorInherited(fdWriteEnd, false) } #endif @@ -609,6 +612,72 @@ extension FileHandle { #endif } #endif + +#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) + /// Set whether or not the given file descriptor is inherited by child processes. + /// + /// - Parameters: + /// - fd: The file descriptor. + /// - inherited: Whether or not `fd` is inherited by child processes + /// (ignoring overriding functionality such as Apple's + /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.) + /// + /// - Throws: Any error that occurred while setting the flag. + private static func _setFileDescriptorInherited(_ fd: CInt, _ inherited: Bool) throws { + switch swt_getfdflags(fd) { + case -1: + // An error occurred reading the flags for this file descriptor. + throw CError(rawValue: swt_errno()) + case let oldValue: + let newValue = if inherited { + oldValue & ~FD_CLOEXEC + } else { + oldValue | FD_CLOEXEC + } + if oldValue == newValue { + // No need to make a second syscall as nothing has changed. + return + } + if -1 == swt_setfdflags(fd, newValue) { + // An error occurred setting the flags for this file descriptor. + throw CError(rawValue: swt_errno()) + } + } + } +#endif + + /// Set whether or not this file handle is inherited by child processes. + /// + /// - Parameters: + /// - inherited: Whether or not this file handle is inherited by child + /// processes (ignoring overriding functionality such as Apple's + /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.) + /// + /// - Throws: Any error that occurred while setting the flag. + func setInherited(_ inherited: Bool) throws { +#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) + try withUnsafePOSIXFileDescriptor { fd in + guard let fd else { + throw SystemError(description: "Cannot set whether a file handle is inherited unless it is backed by a file descriptor. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") + } + try withLock { + try Self._setFileDescriptorInherited(fd, inherited) + } + } +#elseif os(Windows) + return try withUnsafeWindowsHANDLE { handle in + guard let handle else { + throw SystemError(description: "Cannot set whether a file handle is inherited unless it is backed by a Windows file handle. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") + } + let newValue = inherited ? DWORD(HANDLE_FLAG_INHERIT) : 0 + guard SetHandleInformation(handle, DWORD(HANDLE_FLAG_INHERIT), newValue) else { + throw Win32Error(rawValue: GetLastError()) + } + } +#else +#warning("Platform-specific implementation missing: cannot set whether a file handle is inherited") +#endif + } } // MARK: - General path utilities @@ -688,35 +757,4 @@ func canonicalizePath(_ path: String) -> String? { return nil #endif } - -#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) -/// Set the given file descriptor's `FD_CLOEXEC` flag. -/// -/// - Parameters: -/// - flag: The new value of `fd`'s `FD_CLOEXEC` flag. -/// - fd: The file descriptor. -/// -/// - Throws: Any error that occurred while setting the flag. -func setFD_CLOEXEC(_ flag: Bool, onFileDescriptor fd: CInt) throws { - switch swt_getfdflags(fd) { - case -1: - // An error occurred reading the flags for this file descriptor. - throw CError(rawValue: swt_errno()) - case let oldValue: - let newValue = if flag { - oldValue & ~FD_CLOEXEC - } else { - oldValue | FD_CLOEXEC - } - if oldValue == newValue { - // No need to make a second syscall as nothing has changed. - return - } - if -1 == swt_setfdflags(fd, newValue) { - // An error occurred setting the flags for this file descriptor. - throw CError(rawValue: swt_errno()) - } - } -} -#endif #endif diff --git a/Sources/Testing/Support/Versions.swift b/Sources/Testing/Support/Versions.swift index 1229e80b0..1eb7f4e48 100644 --- a/Sources/Testing/Support/Versions.swift +++ b/Sources/Testing/Support/Versions.swift @@ -153,30 +153,6 @@ let swiftStandardLibraryVersion: String = { return "unknown" }() -#if canImport(Glibc) -/// The (runtime, not compile-time) version of glibc in use on this system. -/// -/// This value is not part of the public interface of the testing library. -let glibcVersion: (major: Int, minor: Int) = { - // Default to the statically available version number if the function call - // fails for some reason. - var major = Int(clamping: __GLIBC__) - var minor = Int(clamping: __GLIBC_MINOR__) - - if let strVersion = gnu_get_libc_version() { - withUnsafeMutablePointer(to: &major) { major in - withUnsafeMutablePointer(to: &minor) { minor in - withVaList([major, minor]) { args in - _ = vsscanf(strVersion, "%zd.%zd", args) - } - } - } - } - - return (major, minor) -}() -#endif - // MARK: - sysctlbyname() Wrapper #if !SWT_NO_SYSCTL && SWT_TARGET_OS_APPLE diff --git a/Sources/_TestingInternals/include/Includes.h b/Sources/_TestingInternals/include/Includes.h index 1b95151cb..bfc87b001 100644 --- a/Sources/_TestingInternals/include/Includes.h +++ b/Sources/_TestingInternals/include/Includes.h @@ -53,10 +53,6 @@ #include #endif -#if __has_include() -#include -#endif - #if __has_include() && !defined(__wasi__) #include #endif From 0ca2409d28816f51d0b65899cb48b488aefedeb8 Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Mon, 16 Jun 2025 15:59:50 -0700 Subject: [PATCH 2/2] Revert "Disable inheritance of file descriptors created by Swift Testing by default. (#1145)" This reverts commit b0a1efd5e7e9cbb33785cf7e7c0178cac3c1a791. --- Sources/Testing/Attachments/Attachment.swift | 4 +- Sources/Testing/ExitTests/ExitTest.swift | 9 -- Sources/Testing/Support/FileHandle.swift | 135 +------------------ Sources/_TestingInternals/include/Stubs.h | 20 --- 4 files changed, 7 insertions(+), 161 deletions(-) diff --git a/Sources/Testing/Attachments/Attachment.swift b/Sources/Testing/Attachments/Attachment.swift index f8d242c8c..45966c66a 100644 --- a/Sources/Testing/Attachments/Attachment.swift +++ b/Sources/Testing/Attachments/Attachment.swift @@ -473,7 +473,7 @@ extension Attachment where AttachableValue: ~Copyable { // file exists at this path (note "x" in the mode string), an error will // be thrown and we'll try again by adding a suffix. let preferredPath = appendPathComponent(preferredName, to: directoryPath) - file = try FileHandle(atPath: preferredPath, mode: "wxeb") + file = try FileHandle(atPath: preferredPath, mode: "wxb") result = preferredPath } catch { // Split the extension(s) off the preferred name. The first component in @@ -489,7 +489,7 @@ extension Attachment where AttachableValue: ~Copyable { // Propagate any error *except* EEXIST, which would indicate that the // name was already in use (so we should try again with a new suffix.) do { - file = try FileHandle(atPath: preferredPath, mode: "wxeb") + file = try FileHandle(atPath: preferredPath, mode: "wxb") result = preferredPath break } catch let error as CError where error.rawValue == swt_EEXIST() { diff --git a/Sources/Testing/ExitTests/ExitTest.swift b/Sources/Testing/ExitTests/ExitTest.swift index c114117eb..c5579981e 100644 --- a/Sources/Testing/ExitTests/ExitTest.swift +++ b/Sources/Testing/ExitTests/ExitTest.swift @@ -824,15 +824,6 @@ extension ExitTest { childEnvironment["SWT_EXPERIMENTAL_CAPTURED_VALUES"] = capturedValuesEnvironmentVariable } -#if !SWT_TARGET_OS_APPLE - // Set inherited those file handles that the child process needs. On - // Darwin, this is a no-op because we use POSIX_SPAWN_CLOEXEC_DEFAULT. - try stdoutWriteEnd?.setInherited(true) - try stderrWriteEnd?.setInherited(true) - try backChannelWriteEnd.setInherited(true) - try capturedValuesReadEnd.setInherited(true) -#endif - // Spawn the child process. let processID = try withUnsafePointer(to: backChannelWriteEnd) { backChannelWriteEnd in try withUnsafePointer(to: capturedValuesReadEnd) { capturedValuesReadEnd in diff --git a/Sources/Testing/Support/FileHandle.swift b/Sources/Testing/Support/FileHandle.swift index 4e3c17372..2a2bfe967 100644 --- a/Sources/Testing/Support/FileHandle.swift +++ b/Sources/Testing/Support/FileHandle.swift @@ -73,13 +73,6 @@ struct FileHandle: ~Copyable, Sendable { return } - // On Windows, "N" is used rather than "e" to signify that a file handle is - // not inherited. - var mode = mode - if let eIndex = mode.firstIndex(of: "e") { - mode.replaceSubrange(eIndex ... eIndex, with: "N") - } - // Windows deprecates fopen() as insecure, so call _wfopen_s() instead. let fileHandle = try path.withCString(encodedAs: UTF16.self) { path in try mode.withCString(encodedAs: UTF16.self) { mode in @@ -105,13 +98,8 @@ struct FileHandle: ~Copyable, Sendable { /// - path: The path to read from. /// /// - Throws: Any error preventing the stream from being opened. - /// - /// By default, the resulting file handle is not inherited by any child - /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call - /// ``setInherited()``. init(forReadingAtPath path: String) throws { - try self.init(atPath: path, mode: "reb") + try self.init(atPath: path, mode: "rb") } /// Initialize an instance of this type to write to the given path. @@ -120,13 +108,8 @@ struct FileHandle: ~Copyable, Sendable { /// - path: The path to write to. /// /// - Throws: Any error preventing the stream from being opened. - /// - /// By default, the resulting file handle is not inherited by any child - /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call - /// ``setInherited()``. init(forWritingAtPath path: String) throws { - try self.init(atPath: path, mode: "web") + try self.init(atPath: path, mode: "wb") } /// Initialize an instance of this type with an existing C file handle. @@ -462,17 +445,6 @@ extension FileHandle { #if !SWT_NO_PIPES // MARK: - Pipes -#if !SWT_TARGET_OS_APPLE && !os(Windows) && !SWT_NO_DYNAMIC_LINKING -/// Create a pipe with flags. -/// -/// This function declaration is provided because `pipe2()` is only declared if -/// `_GNU_SOURCE` is set, but setting it causes build errors due to conflicts -/// with Swift's Glibc module. -private let _pipe2 = symbol(named: "pipe2").map { - castCFunction(at: $0, to: (@convention(c) (UnsafeMutablePointer, CInt) -> CInt).self) -} -#endif - extension FileHandle { /// Make a pipe connecting two new file handles. /// @@ -489,37 +461,15 @@ extension FileHandle { /// - Bug: This function should return a tuple containing the file handles /// instead of returning them via `inout` arguments. Swift does not support /// tuples with move-only elements. ([104669935](rdar://104669935)) - /// - /// By default, the resulting file handles are not inherited by any child - /// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and - /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make them inheritable, - /// call ``setInherited()``. static func makePipe(readEnd: inout FileHandle?, writeEnd: inout FileHandle?) throws { -#if !os(Windows) - var pipe2Called = false -#endif - var (fdReadEnd, fdWriteEnd) = try withUnsafeTemporaryAllocation(of: CInt.self, capacity: 2) { fds in #if os(Windows) - guard 0 == _pipe(fds.baseAddress, 0, _O_BINARY | _O_NOINHERIT) else { + guard 0 == _pipe(fds.baseAddress, 0, _O_BINARY) else { throw CError(rawValue: swt_errno()) } #else -#if !SWT_TARGET_OS_APPLE && !os(Windows) && !SWT_NO_DYNAMIC_LINKING - if let _pipe2 { - guard 0 == _pipe2(fds.baseAddress!, O_CLOEXEC) else { - throw CError(rawValue: swt_errno()) - } - pipe2Called = true - } -#endif - - if !pipe2Called { - // pipe2() is not available. Use pipe() instead and simulate O_CLOEXEC - // to the best of our ability. - guard 0 == pipe(fds.baseAddress!) else { - throw CError(rawValue: swt_errno()) - } + guard 0 == pipe(fds.baseAddress!) else { + throw CError(rawValue: swt_errno()) } #endif return (fds[0], fds[1]) @@ -529,15 +479,6 @@ extension FileHandle { Self._close(fdWriteEnd) } -#if !os(Windows) - if !pipe2Called { - // pipe2() is not available. Use pipe() instead and simulate O_CLOEXEC - // to the best of our ability. - try _setFileDescriptorInherited(fdReadEnd, false) - try _setFileDescriptorInherited(fdWriteEnd, false) - } -#endif - do { defer { fdReadEnd = -1 @@ -612,72 +553,6 @@ extension FileHandle { #endif } #endif - -#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) - /// Set whether or not the given file descriptor is inherited by child processes. - /// - /// - Parameters: - /// - fd: The file descriptor. - /// - inherited: Whether or not `fd` is inherited by child processes - /// (ignoring overriding functionality such as Apple's - /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.) - /// - /// - Throws: Any error that occurred while setting the flag. - private static func _setFileDescriptorInherited(_ fd: CInt, _ inherited: Bool) throws { - switch swt_getfdflags(fd) { - case -1: - // An error occurred reading the flags for this file descriptor. - throw CError(rawValue: swt_errno()) - case let oldValue: - let newValue = if inherited { - oldValue & ~FD_CLOEXEC - } else { - oldValue | FD_CLOEXEC - } - if oldValue == newValue { - // No need to make a second syscall as nothing has changed. - return - } - if -1 == swt_setfdflags(fd, newValue) { - // An error occurred setting the flags for this file descriptor. - throw CError(rawValue: swt_errno()) - } - } - } -#endif - - /// Set whether or not this file handle is inherited by child processes. - /// - /// - Parameters: - /// - inherited: Whether or not this file handle is inherited by child - /// processes (ignoring overriding functionality such as Apple's - /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.) - /// - /// - Throws: Any error that occurred while setting the flag. - func setInherited(_ inherited: Bool) throws { -#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) - try withUnsafePOSIXFileDescriptor { fd in - guard let fd else { - throw SystemError(description: "Cannot set whether a file handle is inherited unless it is backed by a file descriptor. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") - } - try withLock { - try Self._setFileDescriptorInherited(fd, inherited) - } - } -#elseif os(Windows) - return try withUnsafeWindowsHANDLE { handle in - guard let handle else { - throw SystemError(description: "Cannot set whether a file handle is inherited unless it is backed by a Windows file handle. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") - } - let newValue = inherited ? DWORD(HANDLE_FLAG_INHERIT) : 0 - guard SetHandleInformation(handle, DWORD(HANDLE_FLAG_INHERIT), newValue) else { - throw Win32Error(rawValue: GetLastError()) - } - } -#else -#warning("Platform-specific implementation missing: cannot set whether a file handle is inherited") -#endif - } } // MARK: - General path utilities diff --git a/Sources/_TestingInternals/include/Stubs.h b/Sources/_TestingInternals/include/Stubs.h index 636ea9aff..ad1a84d13 100644 --- a/Sources/_TestingInternals/include/Stubs.h +++ b/Sources/_TestingInternals/include/Stubs.h @@ -160,26 +160,6 @@ static int swt_EEXIST(void) { return EEXIST; } -#if defined(F_GETFD) -/// Call `fcntl(F_GETFD)`. -/// -/// This function is provided because `fcntl()` is a variadic function and -/// cannot be imported directly into Swift. -static int swt_getfdflags(int fd) { - return fcntl(fd, F_GETFD); -} -#endif - -#if defined(F_SETFD) -/// Call `fcntl(F_SETFD)`. -/// -/// This function is provided because `fcntl()` is a variadic function and -/// cannot be imported directly into Swift. -static int swt_setfdflags(int fd, int flags) { - return fcntl(fd, F_SETFD, flags); -} -#endif - SWT_ASSUME_NONNULL_END #endif