Host-Key-Popup mit Fingerprint + ctty-run-Helper (Ctty fuer ssh-Prompts), Doku
This commit is contained in:
@@ -80,10 +80,22 @@ final class PTYSession: ObservableObject {
|
||||
}
|
||||
masterFD = master
|
||||
|
||||
// Ctty-Helper (gleiches Verzeichnis wie dieses Binary — .app wie .build):
|
||||
// Gibt ssh ein echtes Controlling-Terminal, damit Passwort- und
|
||||
// Yes/No-Prompts funktionieren (/dev/tty statt stiller Abbrüche).
|
||||
// Ohne Helper: Legacy-Direktstart (Prompts teils stumm).
|
||||
let pipe = Pipe()
|
||||
let p = Process()
|
||||
p.executableURL = URL(fileURLWithPath: executable)
|
||||
p.arguments = arguments
|
||||
if let helper = Self.cttyHelperURL() {
|
||||
p.executableURL = helper
|
||||
p.arguments = [slavePath, executable] + arguments
|
||||
} else {
|
||||
p.executableURL = URL(fileURLWithPath: executable)
|
||||
p.arguments = arguments
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.note("Hinweis: ohne ctty-run-Helper (eingeschränkte Prompts).")
|
||||
}
|
||||
}
|
||||
var env = ProcessInfo.processInfo.environment
|
||||
env["TERM"] = "xterm-256color"
|
||||
if env["LANG"] == nil { env["LANG"] = "de_DE.UTF-8" }
|
||||
@@ -225,6 +237,17 @@ final class PTYSession: ObservableObject {
|
||||
lines = [[]]
|
||||
}
|
||||
|
||||
/// ctty-run liegt neben diesem Binary (Contents/MacOS wie .build/debug).
|
||||
static func cttyHelperURL() -> URL? {
|
||||
let sibling = URL(fileURLWithPath: CommandLine.arguments[0])
|
||||
.deletingLastPathComponent()
|
||||
.appendingPathComponent("ctty-run")
|
||||
if FileManager.default.isExecutableFile(atPath: sibling.path) {
|
||||
return sibling
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func note(_ message: String) {
|
||||
lines.append([StyledText(text: message, style: TermStyle(fg: 8))])
|
||||
}
|
||||
@@ -241,7 +264,7 @@ final class PTYSession: ObservableObject {
|
||||
|
||||
func stop() {
|
||||
let wasRunning = isRunning
|
||||
process?.terminate()
|
||||
killTree()
|
||||
cleanupSync()
|
||||
if wasRunning {
|
||||
epoch += 1 // späte terminationHandler-Ausläufer verwerfen
|
||||
@@ -252,6 +275,14 @@ final class PTYSession: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// Beendet Kind + Enkel (ctty-run-Wächter + ssh teilen die Prozessgruppe).
|
||||
private func killTree() {
|
||||
if let pid = process?.processIdentifier, pid > 0 {
|
||||
Darwin.kill(-pid, SIGTERM)
|
||||
}
|
||||
process?.terminate()
|
||||
}
|
||||
|
||||
/// Synchroner Cleanup auf Main: Source canceln, Master schließen, Pipe abklemmen.
|
||||
/// Laufende ioQueue-Reads bekommen EBADF und beenden sich selbst.
|
||||
private func cleanupSync() {
|
||||
@@ -278,6 +309,9 @@ final class PTYSession: ObservableObject {
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let pid = process?.processIdentifier, pid > 0 {
|
||||
Darwin.kill(-pid, SIGTERM)
|
||||
}
|
||||
process?.terminate()
|
||||
readSource?.cancel()
|
||||
if masterFD >= 0 { close(masterFD) }
|
||||
|
||||
Reference in New Issue
Block a user