Currently TTY has a lot of flaws:
- The TTY operations are character-based. This tends is hard to work with and requires extra buffers and code complexity and is slow. For instance, the default Node
getChar implementation creates a temporary buffer, uses readSync() which writes into a buffer, and then has to return one character at a time from that buffer. But the stream API calls read() with a buffer, it's only TTY's read implementation that calls getChar() repeatedly and it is more complicated because of it.
- In Node, stdin/stdout/stderr should default to having isatty reflect the value on
process.stdin/ stdout/stderr.
TTY.register() always creates a TTY with isatty() returning true and requires getChar() / putChar(). If I want TTY to be false, I have to make read and write handlers instead. This makes (2) unnecessarily difficult.
- If reading from stdin is implemented with
prompt(), isatty(stdin) should be false, since prompt does not behave like a tty. If writing to stdout/stderr is implemented with console.log() or console.warn() isatty should be false since partial lines are not handled well.
I work around this in Pyodide by avoiding use of TTY, and instead using my own implementation: https://github.com/pyodide/pyodide/blob/main/src/js/streams.ts
But I keep having to copy parts of this into other projects, for instance CPython has its own copy here:
https://github.com/python/cpython/blob/main/Platforms/emscripten/streams.mjs
It would be helpful to solve this in Emscripten.
For the performance part of this, see #16755.
Currently TTY has a lot of flaws:
getCharimplementation creates a temporary buffer, usesreadSync()which writes into a buffer, and then has to return one character at a time from that buffer. But the stream API callsread()with a buffer, it's only TTY'sreadimplementation that callsgetChar()repeatedly and it is more complicated because of it.process.stdin/ stdout/stderr.TTY.register()always creates a TTY withisatty()returningtrueand requiresgetChar()/putChar(). If I want TTY to be false, I have to make read and write handlers instead. This makes (2) unnecessarily difficult.prompt(),isatty(stdin)should be false, since prompt does not behave like a tty. If writing to stdout/stderr is implemented withconsole.log()orconsole.warn()isattyshould be false since partial lines are not handled well.I work around this in Pyodide by avoiding use of TTY, and instead using my own implementation: https://github.com/pyodide/pyodide/blob/main/src/js/streams.ts
But I keep having to copy parts of this into other projects, for instance CPython has its own copy here:
https://github.com/python/cpython/blob/main/Platforms/emscripten/streams.mjs
It would be helpful to solve this in Emscripten.
For the performance part of this, see #16755.