diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0572ea6..805740b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -24,7 +24,6 @@ jobs: dnf install -y procps fi windows_swift_versions: '["6.1", "nightly-main"]' - windows_build_command: 'swift build' enable_macos_checks: true macos_xcode_versions: '["16.3"]' diff --git a/Package.swift b/Package.swift index 0badc42..0e9c521 100644 --- a/Package.swift +++ b/Package.swift @@ -6,7 +6,7 @@ import PackageDescription var dep: [Package.Dependency] = [ .package( url: "https://github.com/apple/swift-system", - from: "1.4.2" + from: "1.5.0" ) ] #if !os(Windows) diff --git a/Sources/Subprocess/Platforms/Subprocess+Windows.swift b/Sources/Subprocess/Platforms/Subprocess+Windows.swift index a397e8a..3dfb00c 100644 --- a/Sources/Subprocess/Platforms/Subprocess+Windows.swift +++ b/Sources/Subprocess/Platforms/Subprocess+Windows.swift @@ -1014,7 +1014,7 @@ extension FileDescriptor { case .failure(let error): continuation.resume(throwing: error) case .success(let bytes): - continuation.resume(returning: bytes) + continuation.resume(returning: bytes.isEmpty ? nil : bytes) } } } diff --git a/Tests/SubprocessTests/SubprocessTests+Windows.swift b/Tests/SubprocessTests/SubprocessTests+Windows.swift index ed67810..3c615e9 100644 --- a/Tests/SubprocessTests/SubprocessTests+Windows.swift +++ b/Tests/SubprocessTests/SubprocessTests+Windows.swift @@ -476,19 +476,34 @@ extension SubprocessWindowsTests { platformOptions: platformOptions, output: .string ) - #expect(whoamiResult.terminationStatus.isSuccess) - let result = try #require( - whoamiResult.standardOutput - ).trimmingCharacters(in: .whitespacesAndNewlines) - // whoami returns `computerName\userName`. - let userInfo = result.split(separator: "\\") - guard userInfo.count == 2 else { - Issue.record("Fail to parse the result for whoami: \(result)") - return + + try await withKnownIssue { + #expect(whoamiResult.terminationStatus.isSuccess) + let result = try #require( + whoamiResult.standardOutput + ).trimmingCharacters(in: .whitespacesAndNewlines) + // whoami returns `computerName\userName`. + let userInfo = result.split(separator: "\\") + guard userInfo.count == 2 else { + Issue.record("Fail to parse the result for whoami: \(result)") + return + } + #expect( + userInfo[1].lowercased() == username.lowercased() + ) + } when: { + func userName() -> String { + var capacity = UNLEN + 1 + let pointer = UnsafeMutablePointer.allocate(capacity: Int(capacity)) + defer { pointer.deallocate() } + guard GetUserNameW(pointer, &capacity) else { + return "" + } + return String(decodingCString: pointer, as: UTF16.self) + } + // CreateProcessWithLogonW doesn't appear to work when running in a container + return whoamiResult.terminationStatus == .unhandledException(STATUS_DLL_INIT_FAILED) && userName() == "ContainerAdministrator" } - #expect( - userInfo[1].lowercased() == username.lowercased() - ) } } @@ -528,7 +543,7 @@ extension SubprocessWindowsTests { ).trimmingCharacters(in: .whitespacesAndNewlines) // Make sure the child console is different from parent #expect( - "\(intptr_t(bitPattern: parentConsole))" == differentConsoleValue + "\(intptr_t(bitPattern: parentConsole))" != differentConsoleValue ) } @@ -707,13 +722,13 @@ extension SubprocessWindowsTests { WaitForSingleObject(processHandle, INFINITE) // Up to 10 characters because Windows process IDs are DWORDs (UInt32), whose max value is 10 digits. + try writeFd.close() let data = try await readFd.readUntilEOF(upToLength: 10) let resultPID = try #require( String(data: data, encoding: .utf8) ).trimmingCharacters(in: .whitespacesAndNewlines) #expect("\(pid.value)" == resultPID) try readFd.close() - try writeFd.close() } }