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