Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simulator detect #107

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions ETTrace/ETTraceRunner/ConnectivityHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ConnectivityHelper.swift
// ETTrace
//
// Created by Noah Martin on 2/27/25.
//

import Foundation

func isPortInUse(port: Int) -> Bool {
let sock = socket(AF_INET, SOCK_STREAM, 0)
if sock == -1 {
print("Failed to create socket")
return false
}

var addr = sockaddr_in()
addr.sin_len = UInt8(MemoryLayout<sockaddr_in>.size);
addr.sin_family = sa_family_t(AF_INET)
addr.sin_port = in_port_t(port).bigEndian
addr.sin_addr.s_addr = INADDR_LOOPBACK.bigEndian

let result = withUnsafePointer(to: &addr) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
connect(sock, $0, socklen_t(MemoryLayout<sockaddr_in>.size))
}
}

close(sock)

return result == 0
}
62 changes: 62 additions & 0 deletions ETTrace/ETTraceRunner/ProcessSelector.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// ProcessSelector.swift
// ETTrace
//
// Created by Noah Martin on 2/27/25.
//

import Foundation

struct RunningProcess {
let path: String
let pid: Int
let bundleID: String?
}

func trimPath(_ path: String) -> String {
let pattern = "/([^/]+\\.app)/"
if let range = path.range(of: pattern, options: .regularExpression) {
return String(path[range.lowerBound...])
}
return path
}

func listRunningProcesses() -> [RunningProcess] {
var results: [RunningProcess] = []
let numberOfProcesses = proc_listpids(UInt32(PROC_ALL_PIDS), 0, nil, 0) / Int32(MemoryLayout<pid_t>.size)
guard numberOfProcesses > 0 else { return [] }

var pids = [pid_t](repeating: 0, count: Int(numberOfProcesses))

let result = proc_listpids(UInt32(PROC_ALL_PIDS), 0, &pids, Int32(pids.count * MemoryLayout<pid_t>.size))
guard result > 0 else { return [] }

for pid in pids {
if pid == 0 { continue }

var pathBuffer = [CChar](repeating: 0, count: 4 * 1024)

let pathResult = proc_pidpath(pid, &pathBuffer, UInt32(pathBuffer.count))
if pathResult > 0 {
let path = String(cString: pathBuffer)
if path.contains("CoreSimulator/Devices/") {
let url = URL(fileURLWithPath: path)
var bundleID: String? = nil
var bundleURL = url
while bundleURL.pathComponents.count > 1 {
if bundleURL.pathExtension == "app" {
break
}
bundleURL.deleteLastPathComponent()
}

if bundleURL.pathExtension == "app",
let bundle = Bundle(url: bundleURL) {
bundleID = bundle.bundleIdentifier
}
results.append(.init(path: trimPath(path), pid: Int(pid), bundleID: bundleID))
}
}
}
return results
}
27 changes: 22 additions & 5 deletions ETTrace/ETTraceRunner/RunnerHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,29 @@ class RunnerHelper {
}

func start() async throws {
print("Please open the app on the \(useSimulator ? "simulator" : "device")")
if !useSimulator {
print("Re-run with `--simulator` to connect to the simulator.")
if !useSimulator || !isPortInUse(port: Int(PTPortNumber)) {
// App is not ready to connect
if useSimulator {
let running = listRunningProcesses()
if !running.isEmpty {
print("\(running.count) app\(running.count == 1 ? " was" : "s were") found but \(running.count == 1 ? "it is" : "they are") not running ettrace.")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be easier to follow if you did running.count == 1 ? "1 app was found but it is not running" : "\(running.count) apps were found but they are not running"

for p in running {
if let bundleId = p.bundleID {
print("\tBundle Id: \(bundleId) path: \(p.path)")
} else {
print("\tPath: \(p.path)")
}
}
}
}

print("Please open the app on the \(useSimulator ? "simulator" : "device")")
if !useSimulator {
print("Re-run with `--simulator` to connect to the simulator.")
}
print("Press return when ready...")
_ = readLine()
}
print("Press return when ready...")
_ = readLine()

print("Connecting to device.")

Expand Down