Re: [RFC] Io\Terminal

From: Date: Mon, 05 Oct 2026 11:32:25 +0000
Subject: Re: [RFC] Io\Terminal
References: 1 2 3 4 5 6 7 8 9 10 11  Groups: php.internals 
Request: Send a blank email to internals+get-132785@lists.php.net to get a copy of this message
Hi Pratik, On Fri, Oct 2, 2026, Pratik Bhujel wrote: I have not changed the RFC or implementation yet. I would like to settle > this point before making another API change, so that the RFC can go into > the next stage with this part resolved rather than carrying the > disagreement forward. The remaining question for me is what testing seam we > want cross-platform userland code which directly consumes readKey() to > have, without keeping the ModeToken problem Tim pointed out. > I agree with Tim and Bob: drop both interfaces and rename SystemTerminal to Terminal. The Windows gap closes if readKey() and readSecret() stop rejecting non-terminal input. A pipe or php://memory stream already delivers bytes unprocessed, which is all raw mode does to a tty. So on a non-terminal stream, readKey() can run the POSIX byte decoder, enableRawMode() can return a lease that changes nothing, and readSecret() can read to the newline. Tests then use php://memory on every OS. Callers that need a real terminal have stream_isatty(). readLine() already accepts redirected input, so this keeps the API consistent. Three other things: 1. Specify raw mode. On POSIX the patch clears OPOST and ISIG (cfmakeraw). Symfony's "-icanon -echo" and Laravel Prompts' "-icanon -isig -echo" clear neither. With OPOST off, every "\n" output during a lease staircases on POSIX but not on Windows, because the console's output mode is never touched. Keep OPOST, or state the flags in the RFC and make Windows match. 2. pcntl_fork(): the child inherits the lease list, and its RSHUTDOWN restores the shared tty, so a TUI loses raw mode when a worker exits. Store the pid that acquired the lease and skip restoring in any other process. 3. Drop the retained token and the no-argument restoreMode(). A lease that stays active after the caller's variable is unset undoes the RAII guarantee. With the token as the only owner, Nicolas's refcount design covers everything. Also, adding a Key case later breaks any match() without a default arm, so add Insert and Shift+Tab now. -- Ilia Alshanetsky Technologist, CTO, Entrepreneur E: ilia@ilia.ws T: @iliaa B: http://ilia.ws

« previous php.internals (#132785) next »