Spaces:
Paused
Paused
| import asyncio | |
| import os | |
| import pty | |
| import select | |
| class TerminalBridge: | |
| def __init__(self): | |
| self.sessions = {} | |
| async def connect(self, websocket): | |
| pid, fd = pty.fork() | |
| if pid == 0: | |
| import os | |
| if pid == 0: | |
| os.makedirs("/data/workspace", exist_ok=True) | |
| os.chdir("/data/workspace") | |
| os.execvp( | |
| "bash", | |
| [ | |
| "bash", | |
| "--login", | |
| "-i" | |
| ] | |
| ) | |
| session = { | |
| "ws": websocket, | |
| "pid": pid, | |
| "fd": fd | |
| } | |
| self.sessions[websocket] = session | |
| asyncio.create_task(self.reader(session)) | |
| return session | |
| async def disconnect(self, session): | |
| try: | |
| os.close(session["fd"]) | |
| except Exception: | |
| pass | |
| self.sessions.pop(session["ws"], None) | |
| async def input(self, session, text): | |
| os.write( | |
| session["fd"], | |
| (text + "\n").encode() | |
| ) | |
| async def reader(self, session): | |
| fd = session["fd"] | |
| while True: | |
| ready, _, _ = select.select( | |
| [fd], | |
| [], | |
| [], | |
| 0.05 | |
| ) | |
| if ready: | |
| try: | |
| data = os.read( | |
| fd, | |
| 4096 | |
| ) | |
| if not data: | |
| break | |
| await session["ws"].send_text( | |
| data.decode(errors="ignore") | |
| ) | |
| except Exception: | |
| break |