1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//
private import _TestingInternals
/// A human-readable string describing the current operating system's version.
///
/// This value's format is platform-specific and is not meant to be
/// machine-readable. It is added to the output of a test run when using
/// an event writer.
///
/// This value is not part of the public interface of the testing library.
let operatingSystemVersion: String = {
#if !SWT_NO_SYSCTL && SWT_TARGET_OS_APPLE
let productVersion = sysctlbyname("kern.osproductversion", as: String.self) ?? ""
let buildNumber = sysctlbyname("kern.osversion", as: String.self) ?? ""
switch (productVersion, buildNumber) {
case ("", ""):
break
case let ("", buildNumber):
return buildNumber
case let (productVersion, ""):
return productVersion
default:
return "\(productVersion) (\(buildNumber))"
}
#elseif !SWT_NO_UNAME && (SWT_TARGET_OS_APPLE || os(Linux) || os(WASI))
var name = utsname()
if 0 == uname(&name) {
let release = withUnsafeBytes(of: name.release) { release in
release.withMemoryRebound(to: CChar.self) { release in
String(validatingCString: release.baseAddress!) ?? ""
}
}
let version = withUnsafeBytes(of: name.version) { version in
version.withMemoryRebound(to: CChar.self) { version in
String(validatingCString: version.baseAddress!) ?? ""
}
}
switch (release, version) {
case ("", ""):
break
case let (release, ""):
return release
case let ("", version):
return version
default:
return "\(release) (\(version))"
}
}
#elseif os(Windows)
// See if we can query the kernel directly, bypassing the fake-out logic added
// in Windows 10 and later that misreports the OS version. GetVersionExW()
// basically always lies on Windows 10, so don't bother calling it on a
// fallback path.
let RtlGetVersion = symbol(in: GetModuleHandleA("ntdll.dll"), named: "RtlGetVersion").map {
unsafeBitCast($0, to: (@convention(c) (UnsafeMutablePointer<OSVERSIONINFOW>) -> NTSTATUS).self)
}
if let RtlGetVersion {
var versionInfo = OSVERSIONINFOW()
versionInfo.dwOSVersionInfoSize = .init(MemoryLayout.stride(ofValue: versionInfo))
if RtlGetVersion(&versionInfo) >= 0 {
var result = "\(versionInfo.dwMajorVersion).\(versionInfo.dwMinorVersion) Build \(versionInfo.dwBuildNumber)"
// Include Service Pack details if available.
if versionInfo.szCSDVersion.0 != 0 {
withUnsafeBytes(of: versionInfo.szCSDVersion) { szCSDVersion in
szCSDVersion.withMemoryRebound(to: wchar_t.self) { szCSDVersion in
if let szCSDVersion = String.decodeCString(szCSDVersion.baseAddress!, as: UTF16.self)?.result {
result += " (\(szCSDVersion))"
}
}
}
}
return result
}
}
#elseif os(WASI)
if let libcVersion = swt_getWASIVersion().flatMap(String.init(validatingCString:)), !libcVersion.isEmpty {
return "WASI with libc \(libcVersion)"
}
#else
#warning("Platform-specific implementation missing: OS version unavailable")
#endif
return "unknown"
}()
#if targetEnvironment(simulator)
/// A human-readable string describing the simulated operating system's version.
///
/// This value's format is platform-specific and is not meant to be
/// machine-readable. It is added to the output of a test run when using
/// an event writer.
///
/// This value is not part of the public interface of the testing library.
let simulatorVersion: String = {
let productVersion = Environment.variable(named: "SIMULATOR_RUNTIME_VERSION") ?? ""
let buildNumber = Environment.variable(named: "SIMULATOR_RUNTIME_BUILD_VERSION") ?? ""
switch (productVersion, buildNumber) {
case ("", ""):
return "unknown"
case let ("", buildNumber):
return buildNumber
case let (productVersion, ""):
return productVersion
default:
return "\(productVersion) (\(buildNumber))"
}
}()
#endif
/// A human-readable string describing the testing library's version.
///
/// This value's format is platform-specific and is not meant to be
/// machine-readable. It is added to the output of a test run when using
/// an event writer.
///
/// This value is not part of the public interface of the testing library.
var testingLibraryVersion: String {
swt_getTestingLibraryVersion().flatMap(String.init(validatingCString:)) ?? "unknown"
}
/// A human-readable string describing the Swift Standard Library's version.
///
/// This value's format is platform-specific and is not meant to be
/// machine-readable. It is added to the output of a test run when using
/// an event writer.
///
/// This value is not part of the public interface of the testing library.
let swiftStandardLibraryVersion: String = {
if #available(_swiftVersionAPI, *) {
return String(describing: _SwiftStdlibVersion.current)
}
return "unknown"
}()
// MARK: - sysctlbyname() Wrapper
#if !SWT_NO_SYSCTL && SWT_TARGET_OS_APPLE
/// Get a string value by calling `sysctlbyname()`.
///
/// - Parameters:
/// - name: The name of the value to get, such as `"kern.osversion"`.
///
/// - Returns: A string containing the requested value interpreted as a UTF-8
/// string, or `nil` if the value could not be read or could not be
/// interpreted as UTF-8.
///
/// This function is not part of the public interface of the testing library.
func sysctlbyname(_ name: String, as _: String.Type) -> String? {
name.withCString { name in
var szValue = 0
if 0 == sysctlbyname(name, nil, &szValue, nil, 0) {
return withUnsafeTemporaryAllocation(of: CChar.self, capacity: szValue) { buffer in
if 0 == sysctlbyname(name, buffer.baseAddress!, &szValue, nil, 0) {
return String(validatingCString: buffer.baseAddress!)
}
return nil
}
}
return nil
}
}
#endif
|