From a3b3018de7ca3538d585a930221587f16a0e4e37 Mon Sep 17 00:00:00 2001 From: CakeCN Date: Wed, 7 Jan 2026 00:57:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E6=96=AD=E5=BC=80?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=90=8E=EF=BC=8C=E6=96=87=E4=BB=B6=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E7=AC=A6=E5=B7=B2=E7=BB=8F=E8=A2=AB=E5=85=B3=E9=97=AD?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E4=BB=8D=E6=9C=89=E4=BA=8B=E4=BB=B6=E5=9C=A8?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=B8=AD=EF=BC=9A=E5=AF=B9=20app/sockets/ter?= =?UTF-8?q?minal=5Fservice.py=20=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E5=85=A8=E9=9D=A2=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/sockets/terminal_service.py | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/code-server-like/app/sockets/terminal_service.py b/code-server-like/app/sockets/terminal_service.py index 3d33442..cc41312 100644 --- a/code-server-like/app/sockets/terminal_service.py +++ b/code-server-like/app/sockets/terminal_service.py @@ -29,8 +29,12 @@ terminal_bp = Blueprint('terminal', __name__, url_prefix='/vsc-like') def set_winsize(fd, row, col, xpix=0, ypix=0): - winsize = struct.pack("HHHH", row, col, xpix, ypix) - fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize) + try: + winsize = struct.pack("HHHH", row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize) + except (OSError, IOError): + # File descriptor closed or invalid, do nothing + pass def read_and_forward_pty_output(fd=None, pid=None, room_id=None,namespace=None): @@ -172,7 +176,13 @@ class VSCLikeNameSpace(Namespace): if fd: # print("writing to ptd: %s" % data["input"]) # os.write(fd, data["input"].encode('ascii')) - os.write(fd, data["input"].encode()) + try: + os.write(fd, data["input"].encode()) + except (OSError, IOError): + # File descriptor closed or invalid, clean up + disconnect() + session['terminal_config'] = TERM_INIT_CONFIG + return def on_resize(self, data): @@ -188,10 +198,29 @@ class VSCLikeNameSpace(Namespace): return fd = session.get('terminal_config').get('fd') if fd: - set_winsize(fd, data["rows"], data["cols"]) + # 检查文件描述符是否有效 + try: + # 尝试一个简单的操作来检查文件描述符是否有效 + os.fstat(fd) + set_winsize(fd, data["rows"], data["cols"]) + except (OSError, IOError): + # 文件描述符无效,清理资源 + disconnect() + session['terminal_config'] = TERM_INIT_CONFIG + return def on_disconnect(self): - child_pid = session.get('terminal_config', {}).get('child_pid') + terminal_config = session.get('terminal_config', {}) + child_pid = terminal_config.get('child_pid') + fd = terminal_config.get('fd') + + # 先关闭文件描述符,避免其他操作尝试使用无效的文件描述符 + if fd: + try: + os.close(fd) + except Exception: + pass + if child_pid: try: child_process = psutil.Process(child_pid) @@ -210,21 +239,14 @@ class VSCLikeNameSpace(Namespace): pass except psutil.TimeoutExpired: # If process didn't terminate in time, kill it forcefully - child_process.kill() try: + child_process.kill() child_process.wait(timeout=1) except Exception: pass except Exception as err: current_app.logger.error(f'Error terminating process: {err}') - finally: - # Close the file descriptor if it's open - fd = session.get('terminal_config', {}).get('fd') - if fd: - try: - os.close(fd) - except Exception: - pass - # Reset session config - session['terminal_config'] = TERM_INIT_CONFIG + + # Reset session config + session['terminal_config'] = TERM_INIT_CONFIG current_app.logger.debug('Client disconnected') \ No newline at end of file