From 59019ff22b1676bf44fbece0fcc5e00b494dcd93 Mon Sep 17 00:00:00 2001 From: YR Chen Date: Sat, 19 Dec 2020 12:26:26 +0800 Subject: [PATCH] Implement `commandLineFitsWithinSystemLimits` and `tokenizeResponseFile` for Windows --- Sources/SwiftDriver/Driver/Driver.swift | 2 +- Sources/SwiftDriver/Utilities/System.swift | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index e832a353b..93f5750f4 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -744,7 +744,7 @@ extension Driver { /// /// - Parameter content: response file's content to be tokenized. private static func tokenizeResponseFile(_ content: String) -> [String] { - #if !os(macOS) && !os(Linux) && !os(Android) + #if !os(macOS) && !os(Linux) && !os(Android) && !os(Windows) #warning("Response file tokenization unimplemented for platform; behavior may be incorrect") #endif return content.split { $0 == "\n" || $0 == "\r\n" } diff --git a/Sources/SwiftDriver/Utilities/System.swift b/Sources/SwiftDriver/Utilities/System.swift index dc2159272..5738c440a 100644 --- a/Sources/SwiftDriver/Utilities/System.swift +++ b/Sources/SwiftDriver/Utilities/System.swift @@ -12,6 +12,8 @@ #if os(macOS) import Darwin +#elseif os(Windows) +import WinSDK.core.file #elseif canImport(Glibc) import Glibc #endif @@ -46,6 +48,25 @@ func commandLineFitsWithinSystemLimits(path: String, args: [String]) -> Bool { } return commandLineLength < effectiveArgMax } +#elseif os(Windows) +// See: https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation +func commandLineFitsWithinSystemLimits(path: String, args: [String]) -> Bool { + // Known limit for all CreateProcess APIs. + guard path.utf8.count + args.map(\.count).reduce(0, +) < 32_767 else { + return false + } + + // Path component length limit for Unicode APIs. + var length: UInt32 = 0 + withUnsafeMutablePointer(to: &length) { ptr -> Void in + GetVolumeInformationA(nil, nil, 0, nil, ptr, nil, nil, 0) + } + guard path.split(separator: "\\").reduce(true, { result, component in + result && component.utf8.count < length + }) else { return false } + + return true +} #else func commandLineFitsWithinSystemLimits(path: String, args: [String]) -> Bool { #warning("missing implementation for current platform")