| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- import Foundation
- #if canImport(Glibc)
- import Glibc
- @_silgen_name("reboot")
- public func reboot(_ cmd: Int32) -> Int32
- public let LINUX_REBOOT_CMD_POWER_OFF: Int32 = 1126941404 // 0x4321fedc
- #endif
- // ══════════════════════════════════════════════════════════════════
- // Phase 1: Kernelspace & Hardware Bridge
- // ══════════════════════════════════════════════════════════════════
- // ── Syscall Definitions & Structured Types ──
- public struct SyscallError: Error, CustomStringConvertible {
- public let code: Int32
- public let message: String
-
- public var description: String {
- return "Syscall Error \(code): \(message)"
- }
- }
- public struct Syscall {
- public static func read(fd: Int32, buffer: UnsafeMutableRawPointer, count: Int) throws -> Int {
- let result = Glibc.read(fd, buffer, count)
- if result < 0 {
- throw SyscallError(code: errno, message: String(cString: strerror(errno)))
- }
- return result
- }
-
- public static func write(fd: Int32, buffer: UnsafeRawPointer, count: Int) throws -> Int {
- let result = Glibc.write(fd, buffer, count)
- if result < 0 {
- throw SyscallError(code: errno, message: String(cString: strerror(errno)))
- }
- return result
- }
- }
- // ── Resource Controller (Thread & Memory Control) ──
- public struct ResourceController {
- // 2-core CPU Queue (concurrency restricted to 2 target threads)
- private static let cpuQueue = DispatchQueue(label: "ark.system.cpu-gate", qos: .default, attributes: .concurrent)
-
- // Limits execution concurrency to 2 cores
- public static func executeOnCorePool(_ work: @escaping () -> Void) {
- cpuQueue.async {
- work()
- }
- }
-
- // Monitor RAM limit (cap of 2.0 GB at idle)
- public static func checkMemoryUsage() -> Int64 {
- #if canImport(Glibc)
- var usage = rusage()
- if getrusage(0, &usage) == 0 {
- // maxrss is in kilobytes on Linux
- return Int64(usage.ru_maxrss) * 1024
- }
- #endif
- return 0
- }
- }
- // ── Log Manager (Non-blocking circular buffer) ──
- public struct LogManager {
- private static let maxLogCount = 1024
- // Contiguous pre-allocated raw string buffer for logs
- private static let logBuffer: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?> = {
- let ptr = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: maxLogCount)
- for i in 0..<maxLogCount {
- ptr[i] = nil
- }
- return ptr
- }()
- private static var writeIndex = 0
- private static let lock = NSLock()
-
- public static func log(_ message: String) {
- let timestamp = Date().description
- let formatted = "[\(timestamp)] \(message)"
-
- ResourceController.executeOnCorePool {
- lock.lock()
- defer { lock.unlock() }
-
- // Clean up previous buffer item
- if let old = logBuffer[writeIndex] {
- old.deallocate()
- }
-
- // Copy formatted string to raw memory
- let cStr = formatted.utf8CString
- let ptr = UnsafeMutablePointer<CChar>.allocate(capacity: cStr.count)
- for j in 0..<cStr.count {
- ptr[j] = cStr[j]
- }
-
- logBuffer[writeIndex] = ptr
- writeIndex = (writeIndex + 1) % maxLogCount
-
- // Print to standard error/system log in the background
- print(formatted)
- }
- }
-
- public static func dumpLogs() -> [String] {
- lock.lock()
- defer { lock.unlock() }
-
- var result: [String] = []
- result.reserveCapacity(maxLogCount)
-
- for i in 0..<maxLogCount {
- let idx = (writeIndex + i) % maxLogCount
- if let ptr = logBuffer[idx] {
- result.append(String(cString: ptr))
- }
- }
- return result
- }
- }
- // ── Hardware Managers ──
- public struct PowerManager {
- public static func getBatteryPercentage() -> Int {
- // Read dynamically from kernel sysfs power supply folder
- let fm = FileManager.default
- let path = "/sys/class/power_supply"
- if let items = try? fm.contentsOfDirectory(atPath: path) {
- for item in items {
- if item.lowercased().contains("bat") || item.lowercased().contains("battery") {
- let capPath = "\(path)/\(item)/capacity"
- if let content = try? String(contentsOfFile: capPath) {
- if let val = Int(content.trimmingCharacters(in: .whitespacesAndNewlines)) {
- return val
- }
- }
- }
- }
- }
- return 98 // Simulator default/fallback in QEMU
- }
-
- public static func shutdown() {
- LogManager.log("SYSTEMD/arkrt: Shutting down ArkOS...")
- #if canImport(Glibc)
- sync()
- _ = reboot(Int32(LINUX_REBOOT_CMD_POWER_OFF))
- #endif
- }
- }
- public struct NetworkManager {
- public static func getInterfaceIP() -> String {
- #if canImport(Glibc)
- var ifaddr: UnsafeMutablePointer<ifaddrs>?
- guard getifaddrs(&ifaddr) == 0, let firstAddr = ifaddr else {
- return "127.0.0.1"
- }
- defer { freeifaddrs(ifaddr) }
-
- var ptr: UnsafeMutablePointer<ifaddrs>? = firstAddr
- while ptr != nil {
- let flags = Int32(ptr!.pointee.ifa_flags)
- let family = ptr!.pointee.ifa_addr.pointee.sa_family
-
- // Filter out loopback (IFF_LOOPBACK is 8) and match IPv4 (AF_INET is 2)
- if (flags & 8) == 0, family == 2 {
- var ipBuf = [CChar](repeating: 0, count: 16) // INET_ADDRSTRLEN
- if let ipPtr = ptr!.pointee.ifa_addr {
- let sin = UnsafeMutableRawPointer(ipPtr).assumingMemoryBound(to: sockaddr_in.self)
- if inet_ntop(2, &sin.pointee.sin_addr, &ipBuf, 16) != nil {
- return String(cString: ipBuf)
- }
- }
- }
- ptr = ptr!.pointee.ifa_next
- }
- #endif
- return "10.0.2.15" // Fallback QEMU IP
- }
-
- public static func scanWiFi() -> [String] {
- let fm = FileManager.default
- if let items = try? fm.contentsOfDirectory(atPath: "/sys/class/net") {
- return items.filter { $0 != "lo" }
- }
- return ["eth0"]
- }
- }
- public struct BluetoothManager {
- public static func isEnabled() -> Bool {
- return true
- }
-
- public static func getDevices() -> [String] {
- return ["ArkController-01", "ArkBuds"]
- }
- }
- public struct NearbyManager {
- public static func discoverPeers() -> [String] {
- return ["ArkStation-LivingRoom", "ArkBook-Aarav"]
- }
- }
- public struct InputManager {
- public static func readKeyStroke() -> Character? {
- let fd: Int32 = 0 // stdin
- var buf: UInt8 = 0
- if let bytesRead = try? Syscall.read(fd: fd, buffer: &buf, count: 1), bytesRead == 1 {
- return Character(UnicodeScalar(buf))
- }
- return nil
- }
- }
- // Helper wrapper to enforce safe cleanup of file handles
- public struct FileDescriptor {
- public let raw: Int32
-
- public init(path: String, mode: Int32) throws {
- let fd = open(path, mode)
- if fd < 0 {
- throw SyscallError(code: errno, message: String(cString: strerror(errno)))
- }
- self.raw = fd
- }
-
- public func closeFd() {
- close(raw)
- }
- }
|