Attach wsssh stdin/stdout/stderr to xterm.js using threaded output reading

parent d51a378f
...@@ -29,7 +29,6 @@ import os ...@@ -29,7 +29,6 @@ import os
import threading import threading
import uuid import uuid
import subprocess import subprocess
import fcntl
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, send_from_directory from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, send_from_directory
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
...@@ -190,15 +189,31 @@ def connect_terminal(client_id): ...@@ -190,15 +189,31 @@ def connect_terminal(client_id):
command, command,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT
bufsize=0
) )
# Set stdout to non-blocking
fd = proc.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
active_terminals[request_id] = {'client_id': client_id, 'username': username, 'proc': proc} # Start a thread to read output
output_buffer = []
def read_output():
while proc.poll() is None:
try:
data = proc.stdout.read(1024)
if data:
output_buffer.append(data.decode('utf-8', errors='ignore'))
except:
break
# Read any remaining data
try:
data = proc.stdout.read()
if data:
output_buffer.append(data.decode('utf-8', errors='ignore'))
except:
pass
thread = threading.Thread(target=read_output, daemon=True)
thread.start()
active_terminals[request_id] = {'client_id': client_id, 'username': username, 'proc': proc, 'output_buffer': output_buffer}
return jsonify({'request_id': request_id, 'command': ' '.join(command)}) return jsonify({'request_id': request_id, 'command': ' '.join(command)})
...@@ -218,13 +233,12 @@ def terminal_data(client_id): ...@@ -218,13 +233,12 @@ def terminal_data(client_id):
request_id = request.args.get('request_id') request_id = request.args.get('request_id')
if request_id in active_terminals: if request_id in active_terminals:
proc = active_terminals[request_id]['proc'] proc = active_terminals[request_id]['proc']
if proc.poll() is None: output_buffer = active_terminals[request_id]['output_buffer']
try: if output_buffer:
data = proc.stdout.read(1024).decode('utf-8', errors='ignore') data = ''.join(output_buffer)
return data output_buffer.clear()
except: return data
return '' elif proc.poll() is not None:
else:
# Process terminated # Process terminated
return '\r\nProcess terminated.\r\n' return '\r\nProcess terminated.\r\n'
return '' return ''
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment