mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
made read blocking, adnd up to 1024 bytes
request env vars before opeing shell cleanup
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
"location" : "https://github.com/migueldeicaza/SwiftTerm",
|
"location" : "https://github.com/migueldeicaza/SwiftTerm",
|
||||||
"state" : {
|
"state" : {
|
||||||
"branch" : "main",
|
"branch" : "main",
|
||||||
"revision" : "f8e6e08b5a8c8eb0b18b9c250f36121e55c68f49"
|
"revision" : "bf476952af79b2458aac5b5297f1e00598e66007"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssh_channel_request_env(channel, "TERM", "xterm-256color")
|
||||||
|
ssh_channel_request_env(channel, "LANG", "en_US.UTF-8")
|
||||||
|
ssh_channel_request_env(channel, "LC_ALL", "en_US.UTF-8")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try openShell()
|
try openShell()
|
||||||
} catch {
|
} catch {
|
||||||
@@ -90,9 +94,6 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTitle("\(host.username)@\(host.address)")
|
setTitle("\(host.username)@\(host.address)")
|
||||||
ssh_channel_request_env(channel, "TERM", "xterm-256color")
|
|
||||||
ssh_channel_request_env(channel, "LANG", "en_US.UTF-8")
|
|
||||||
ssh_channel_request_env(channel, "LC_ALL", "en_US.UTF-8")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect() throws(SSHError) {
|
func connect() throws(SSHError) {
|
||||||
@@ -380,8 +381,8 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer: [CChar] = Array(repeating: 0, count: 16_384)
|
var buffer: [CChar] = Array(repeating: 0, count: 1024)
|
||||||
let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
|
let nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0)
|
||||||
|
|
||||||
guard nbytes > 0 else { return nil }
|
guard nbytes > 0 else { return nil }
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
|
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
terminalDelegate = self
|
terminalDelegate = self
|
||||||
|
|
||||||
sshQueue.async {
|
sshQueue.async {
|
||||||
Task {
|
Task {
|
||||||
guard let handler = await self.handler else { return }
|
guard let handler = await self.handler else { return }
|
||||||
@@ -32,7 +33,12 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
if let read = handler.readFromChannel() {
|
if let read = handler.readFromChannel() {
|
||||||
Task { [weak self] in
|
Task { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
await self.feed(text: read)
|
await MainActor.run {
|
||||||
|
CATransaction.begin()
|
||||||
|
CATransaction.setDisableActions(true)
|
||||||
|
feed(text: read)
|
||||||
|
CATransaction.commit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try? await Task.sleep(nanoseconds: 10_000_000) //10ms
|
try? await Task.sleep(nanoseconds: 10_000_000) //10ms
|
||||||
@@ -42,31 +48,11 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func resetTerminalView(handler: SSHHandler) {
|
|
||||||
self.handler = handler
|
|
||||||
// terminal.softReset()
|
|
||||||
self.setNeedsDisplay()
|
|
||||||
sshQueue.async {
|
|
||||||
while handler.connected {
|
|
||||||
if let read = handler.readFromChannel() {
|
|
||||||
Task { [weak self] in
|
|
||||||
guard let self else { return }
|
|
||||||
await self.feed(text: read)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Task{ try? await Task.sleep(nanoseconds: 10_000_000) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("unimplemented")
|
fatalError("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
nonisolated public func scrolled(source: TerminalView, position: Double) {
|
nonisolated public func scrolled(source: TerminalView, position: Double) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nonisolated public func setTerminalTitle(source: TerminalView, title: String) {
|
nonisolated public func setTerminalTitle(source: TerminalView, title: String) {
|
||||||
Task {
|
Task {
|
||||||
@@ -76,6 +62,7 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
|
|
||||||
public func sizeChanged(source: TerminalView, newCols: Int, newRows: Int) {
|
public func sizeChanged(source: TerminalView, newCols: Int, newRows: Int) {
|
||||||
try? handler?.resizePTY(toRows: newRows, toCols: newCols)
|
try? handler?.resizePTY(toRows: newRows, toCols: newCols)
|
||||||
|
setNeedsDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func send(source: TerminalView, data: ArraySlice<UInt8>) {
|
public func send(source: TerminalView, data: ArraySlice<UInt8>) {
|
||||||
|
|||||||
@@ -22,9 +22,18 @@ struct TerminalController: UIViewRepresentable {
|
|||||||
handler: handler
|
handler: handler
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tv.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
tv.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
|
||||||
return tv
|
return tv
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUIView(_ tv: TerminalView, context: Context) {
|
func updateUIView(_ tv: TerminalView, context: Context) {
|
||||||
|
tv.setNeedsLayout()
|
||||||
|
tv.layoutIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
static func dismantleUIView(_ uiView: SSHTerminalView, coordinator: ()) {
|
||||||
|
uiView.handler?.disconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user