Skip to content
Merged
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
3 changes: 2 additions & 1 deletion Sources/CopyCat/Broadcast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,11 @@ struct ShellResult: Sendable {
/// Runs a process with stdin detached, capturing stdout and stderr separately
/// so callers can distinguish "no output" from "failed silently". Returns
/// `nil` only when the process couldn't be spawned at all (bad path, etc).
func runShell(_ exec: String, args: [String]) -> ShellResult? {
func runShell(_ exec: String, args: [String], env: [String: String]? = nil) -> ShellResult? {
let p = Process()
p.executableURL = URL(fileURLWithPath: exec)
p.arguments = args
if let env { p.environment = env }
let outPipe = Pipe()
let errPipe = Pipe()
p.standardOutput = outPipe
Expand Down
11 changes: 9 additions & 2 deletions Sources/CopyCat/TailscaleDiscovery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ enum TailscaleDiscovery {
// hosts the user can pick from.
static func allPeers() -> [TailscalePeer] {
guard let bin = executablePath else { return [] }
guard let result = runShell(bin, args: ["status", "--json"]) else {
// TAILSCALE_BE_CLI=1: when the bundled Tailscale binary is invoked from
// a notarized app's subprocess (no TTY), it relaunches the GUI instead
// of running as CLI. The env var forces CLI mode. See
// tailscale/tailscale#16063 and #7140.
let env = ["TAILSCALE_BE_CLI": "1", "PATH": "/usr/bin:/bin"]
guard let result = runShell(bin, args: ["status", "--json"], env: env) else {
Log.app.error("tailscale status: spawn failed for \(bin)")
return []
}
Expand All @@ -36,7 +41,9 @@ enum TailscaleDiscovery {
Log.app.info("tailscale status exit=\(result.exitCode): \(stderr)")
return []
}
return parseTailscalePeers(json: result.stdout)
let peers = parseTailscalePeers(json: result.stdout)
Log.app.info("tailscale status ok: \(peers.count) peers via \(bin)")
return peers
}

static func onlineHostnames() -> [String] {
Expand Down
Loading