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
|
//===----------------------------------------------------------------------===//
//
// 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 the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#if FOUNDATION_FRAMEWORK && !NO_PROCESS
internal import _ForSwiftFoundation
internal import MachO_Private.dyld
internal import CoreFoundation_Private
@objc(_NSSwiftProcessInfo)
internal final class _NSSwiftProcessInfo: ProcessInfo, @unchecked Sendable {
private static let _shared: _NSSwiftProcessInfo = _NSSwiftProcessInfo()
internal static let _globalState: LockedState<GlobalState> = .init(initialState: .init())
internal let _state: LockedState<State>
private let _processInfo: _ProcessInfo
override static var processInfo: ProcessInfo {
return _shared
}
override init() {
_state = .init(initialState: .init())
_processInfo = _ProcessInfo.processInfo
super.init()
}
}
// MARK: - Accessing Process Information
extension _NSSwiftProcessInfo {
override var arguments: [String] { _processInfo.arguments }
override var environment: [String : String] { _processInfo.environment }
override var globallyUniqueString: String { _processInfo.globallyUniqueString }
override var processIdentifier: Int32 { _processInfo.processIdentifier }
override var processName: String {
get { _processInfo.processName }
set { _processInfo.processName = newValue }
}
override var isMacCatalystApp: Bool {
#if (os(macOS) || targetEnvironment(macCatalyst)) && !(FOUNDATION_FRAMEWORK && !canImport(_FoundationICU))
return dyld_get_active_platform() == PLATFORM_MACCATALYST ||
dyld_get_active_platform() == PLATFORM_IOS
#else
return false
#endif
}
override var isiOSAppOnMac: Bool {
#if os(macOS)
return dyld_get_active_platform() == PLATFORM_IOS
#else
return false
#endif
}
}
// MARK: - Accessing User Information
extension _NSSwiftProcessInfo {
#if os(macOS)
override var userName: String { _processInfo.userName }
override var fullUserName: String { _processInfo.fullUserName }
#endif
}
// MARK: - Getting Computer Information
extension _NSSwiftProcessInfo {
override var processorCount: Int { _processInfo.processorCount }
override var activeProcessorCount: Int { _processInfo.activeProcessorCount }
override var physicalMemory: UInt64 { _processInfo.physicalMemory }
override var systemUptime: TimeInterval { _processInfo.systemUptime }
}
// MARK: - Getting Host Information
extension _NSSwiftProcessInfo {
override var hostName: String { _processInfo.hostName }
override var operatingSystemVersionString: String {
// TODO: Move to Swift once Plist is ready
return CFCopySystemVersionString()
.takeRetainedValue() as String
}
override var operatingSystemVersion: OperatingSystemVersion {
var result = OperatingSystemVersion(majorVersion: -1, minorVersion: 0, patchVersion: 0)
var resolvedProductVersionKey = "ProductVersion"
#if os(macOS)
// If we're on a Mac but running an iOS app, use the `iOSSupportVersion` instead
if dyld_get_active_platform() == PLATFORM_IOS {
resolvedProductVersionKey = "iOSSupportVersion"
}
#endif
let productVersion = _CFCopySystemVersionDictionaryValue(resolvedProductVersionKey as CFString)
guard let versionString = productVersion?.takeRetainedValue() as? String else {
return result
}
let components = versionString.split(separator: ".")
guard !components.isEmpty, let major = Int(components[0]) else {
return result
}
result.majorVersion = major
guard components.count > 1, let minor = Int(components[1]) else {
return result
}
result.minorVersion = minor
guard components.count > 2, let patch = Int(components[2]) else {
return result
}
result.patchVersion = patch
return result
}
override func isOperatingSystemAtLeast(_ version: OperatingSystemVersion) -> Bool {
let current = operatingSystemVersion
return current.isVersionAtLeast(version)
}
}
internal extension OperatingSystemVersion {
func isVersionAtLeast(_ version: OperatingSystemVersion) -> Bool {
if self.majorVersion < version.majorVersion {
return false
}
if self.majorVersion > version.majorVersion {
return true
}
if self.minorVersion < version.minorVersion {
return false
}
if self.minorVersion > version.minorVersion {
return true
}
if self.patchVersion < version.patchVersion {
return false
}
if self.patchVersion > version.patchVersion {
return true
}
return true
}
}
#endif // FOUNDATION_FRAMEWORK && !NO_PROCESS
|