fix!: eliminate cat subprocess, use direct stdin reads, fix parens
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).
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user