From c262ea8113a89d5494423033466573873aebff4d Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Sat, 3 Jul 2021 00:34:31 +0700 Subject: [PATCH] Add example of using GodotXterm with socat Uses OS.execute to start socat with a tcp server on one end and shell on te other. Connects to the socat server using StreamPeerTCP. Doesn't support reszing and inherits 'dumb' for the TERM env var so doesn't work too well without updating TERM and resizing with stty. --- examples/socat_terminal/socat_terminal.gd | 52 +++++++++++++++++++++ examples/socat_terminal/socat_terminal.tscn | 14 ++++++ 2 files changed, 66 insertions(+) create mode 100644 examples/socat_terminal/socat_terminal.gd create mode 100644 examples/socat_terminal/socat_terminal.tscn diff --git a/examples/socat_terminal/socat_terminal.gd b/examples/socat_terminal/socat_terminal.gd new file mode 100644 index 0000000..ac0fc19 --- /dev/null +++ b/examples/socat_terminal/socat_terminal.gd @@ -0,0 +1,52 @@ +extends "res://addons/godot_xterm/nodes/terminal/terminal.gd" + +export (String) var exec_path := "bash" +export (String) var socat_path := "socat" # E.g. /usr/bin/socat +export (int) var port := 2023 +export (bool) var verbose := false + +var _timeout = 30 +var _pid: int +var _stream := StreamPeerTCP.new() + + +func _ready(): + var args = ["-v"] if verbose else [] + args.append("tcp-l:%d,reuseaddr,fork" % port) + args.append("exec:%s,pty,setsid,setpgid,stderr,ctty" % exec_path) + + _pid = OS.execute(socat_path, args, false) + + +func _process(delta): + match _stream.get_status(): + StreamPeerTCP.STATUS_NONE, StreamPeerTCP.STATUS_CONNECTING: + _timeout -= 1 + if _timeout < 1: + _error("Timeout: could not connect to socat") + + if not _stream.is_connected_to_host(): + if _stream.connect_to_host("127.0.0.1", port) != OK: + _error("Could not connect to socat") + + StreamPeerTCP.STATUS_CONNECTED: + var avail = _stream.get_available_bytes() + var data = PoolByteArray() + for i in range(avail): + data.append(_stream.get_u8()) + call_deferred("write", data) + + +func _on_Terminal_data_sent(data): + if _stream.get_status() == StreamPeerTCP.STATUS_CONNECTED: + _stream.put_data(data) + + +func _error(message): + push_error(message) + set_process(false) + + +func _exit_tree(): + if OS.kill(_pid) != OK: + push_error("Failed to kill socat") diff --git a/examples/socat_terminal/socat_terminal.tscn b/examples/socat_terminal/socat_terminal.tscn new file mode 100644 index 0000000..2db3443 --- /dev/null +++ b/examples/socat_terminal/socat_terminal.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://examples/socat_terminal/socat_terminal.gd" type="Script" id=1] + +[node name="Terminal" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +focus_mode = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="data_sent" from="." to="." method="_on_Terminal_data_sent"]