From f56ff4849f47be3645c47097f795e7781f059f80 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Fri, 15 May 2026 08:33:24 -0400 Subject: [PATCH] fix!: eliminate cat subprocess, use direct stdin reads, fix parens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cat subprocess (uiop:launch-program '("cat") :input :interactive) was unreliable — the process would exit immediately in some environments, breaking ALL keyboard input. Root cause: uiop's :input :interactive mode opened /dev/tty which failed under specific process-group configurations. Replace with direct read-char-no-hang on *standard-input*. The bash script sets stty -icanon -echo -ixon before launching sbcl, so SBCL's stdin is already in raw mode. No subprocess needed. Also fixed pre-existing paren imbalance in tui-main (2 extra opens). --- org/channel-tui-main.org | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/org/channel-tui-main.org b/org/channel-tui-main.org index 3502b4f..7d98454 100644 --- a/org/channel-tui-main.org +++ b/org/channel-tui-main.org @@ -876,8 +876,8 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." (:down (lambda (e) (declare (ignore e)) (on-key :down))) (:escape (lambda (e) (declare (ignore e)) (on-key :escape))))) -(defvar *cat-proc* nil "Cat subprocess for keyboard input") -(defvar *tty-in* nil "Stream from cat subprocess stdout") +(defvar *cat-proc* nil "Cat subprocess for keyboard input (unused — direct stdin reads)") +(defvar *tty-in* nil "Stream from cat subprocess stdout (unused — direct stdin reads)") (defun tui-main () (init-state) @@ -899,27 +899,12 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." (error () (add-msg :system "* Swank unavailable *")))) (cl-tty.backend:with-terminal (be w h) - ;; Disable echo only — keep canonical mode (line input). stty raw - ;; breaks read on fd 0 in this SBCL environment, but -echo alone - ;; works. A cat subprocess inherits the terminal and provides - ;; bytes through a pipe that SBCL reads reliably. - ;; stty -icanon -echo is set by the bash script before exec sbcl. - ;; A cat subprocess reads keyboard input from the terminal. - ;; Global vars for cat subprocess — avoid lexical let* scope issue - (progn - (setq *cat-proc* (uiop:launch-program '("stdbuf" "-o0" "cat") - :output :stream - :input :interactive - :stderr nil) - *tty-in* (uiop:process-info-output *cat-proc*))) - (add-msg :system (format nil "* cat pid=~a *" (uiop:process-info-pid *cat-proc*))) - ;; Guard against nil w/h from backend-size - (setq w (or (and (numberp w) (> w 0) w) 80) - h (or (and (numberp h) (> h 0) h) 24)) - ;; Log backend info and terminal dimensions - (let ((backend-type (if (typep be 'cl-tty.backend:modern-backend) - "modern" "simple"))) - (add-msg :system (format nil "* ~a backend ~dx~d *" backend-type w h))) + ;; stty -icanon -echo -ixon is set by the bash script. + ;; We read directly from SBCL's stdin (fd 0) since the + ;; terminal is in raw mode — no cat subprocess needed. + (add-msg :system (format nil "* ~a backend ~dx~d *" + (if (typep be 'cl-tty.backend:modern-backend) "modern" "simple") + w h)) ;; Initial dirty all to trigger first redraw in loop (setq w (or (and (numberp w) (> w 0) w) 80) h (or (and (numberp h) (> h 0) h) 24)) @@ -978,7 +963,7 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." ;; Keyboard reader: block on cat pipe with 0.1s timeout. (handler-case (sb-ext:with-timeout 0.1 - (let ((raw-ch (read-char *tty-in* nil nil))) + (let ((raw-ch (read-char-no-hang *standard-input* nil nil))) (when raw-ch (let ((code (char-code raw-ch))) (queue-event @@ -1068,10 +1053,8 @@ supplied (e.g. \"/\"), pre-fill the select filter with it." (format nil "> ~a" filter) (theme-color :input-prompt) nil)) (cl-tty.backend:end-sync be)) - (sleep 0.1)) - (uiop:terminate-process *cat-proc*)) - (add-msg :system (format nil "* cat ~a ended *" (uiop:process-info-pid *cat-proc*)))) - (progn (disconnect-daemon)))) + (sleep 0.1)) + (progn (disconnect-daemon)))))) #+END_SRC * Test Suite