🐛 `Deno.consoleSize()` stabilization lost the ability to find console size when STDOUT/STDERR are redirected
The stabilization of Deno.consoleSize() breaks the ability to determine the console size when STDOUT/STDERR are both redirected.
Minimal example (note: find /v "" == cat for WinOS)...
C> deno --version
deno 1.26.2 (release, x86_64-pc-windows-msvc)
v8 10.7.193.16
typescript 4.8.3
C> :: STDERR/STDOUT redirected
C> deno --unstable eval "const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(f.rid); console.log({size});" 2>&1 | find /v ""
{ size: { columns: 132, rows: 45 } }
This is no longer possible using Deno functions after the stabilization in v1.27.0+ as the rid is now ignored.
C> deno --version
deno 1.31.1 (release, x86_64-pc-windows-msvc)
v8 11.0.226.13
typescript 4.9.4
C> deno --unstable eval "const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(f.rid); console.log({size});"
{ size: { columns: 132, rows: 45 } }
C> :: STDERR/STDOUT redirected
C> deno --unstable eval "const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(f.rid); console.log({size});" 2>NUL | find /v ""
C> :: STDERR/STDOUT redirected (differently ~ another, different bug?!?)
C> deno --unstable eval "const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(f.rid); console.log({size});" 2>&1 | find /v ""
error: Uncaught Error: The handle is invalid. (os error 6)
const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(); console.log({size});
^
at Object.consoleSize (internal:runtime/js/40_tty.js:13:7)
at file:///C:/Users/Roy/OneDrive/Projects/deno/dxx/repo.GH/$deno$eval.js:1:55
C> deno --unstable eval "const size = Deno.consoleSize(); console.log({size});" 2>&1 | find /v ""
error: Uncaught Error: The handle is invalid. (os error 6)
const f = Deno.openSync('CONOUT$'); const size = Deno.consoleSize(); console.log({size});
^
at Object.consoleSize (internal:runtime/js/40_tty.js:13:7)
at file:///C:/Users/Roy/OneDrive/Projects/deno/dxx/repo.GH/$deno$eval.js:1:55
Can this be changed so that if an optional rid is supplied, it is used to determine the console size? Maybe in addition to the three rids now used?
Alternatively, the additional check could be added internally, opening a handle to 'CONOUT$' and testing that for size if the standard handles fail. Some initial testing with another implementation that I've created shows about a 20% increase in total time from 0.5ms to 0.6ms when adding the file open (sync) and testing the resultant ID. If it was tested only if the others failed, it wouldn't add any more time in the usual case but add robustness when needed.
The equivalent Linux code uses '/dev/tty' in place of 'CONOUT$'.
I could offer a PR if desired.
Ping @dsherret , @bartlomieju.
@dsherret , @bartlomieju ,
Just swinging back to this issue after a year or so and seeing your #22162 post...
With deno, it's now currently impossible to determine console size when STDIN, STDOUT, and STDERR are redirected without some sort of hack (ie, using node 😞).
node and bun are able to do this using the method I used prior to the "stabilization" of Deno.consoleSize() which removed the rid. And I now see that FsFile has isTerminal(), but that's it.
As an example, this works for node and bun...
$ node -e "const fs = require('node:fs'); const tty = require('node:tty'); const f = fs.openSync('/dev/tty'); const s = tty.WriteStream(f); console.log({isatty: tty.isatty(f), columns: s.columns, rows: s.rows});" </dev/null 2>&1 | cat
{ isatty: true, columns: 123, rows: 43 }
bun -e "const fs = require('node:fs'); const tty = require('node:tty'); const f = fs.openSync('/dev/tty'); const s = tty.WriteStream(f); console.log({isatty: tty.isatty(f), columns: s.columns, rows: s.rows});" </dev/null 2>&1 | cat
{
isatty: true,
columns: 123,
rows: 43,
}
but is impossible for deno...
$ deno eval "import fs from 'node:fs'; import tty from 'node:tty'; const f = fs.openSync('/de
v/tty'); console.log(tty.isatty(f)); const s = new tty.WriteStream(f); console.log({s});" </dev/null 2>&1 | cat
true
error: Uncaught (in promise) Error: Only fd 0, 1 and 2 are supported.
at new WriteStream (node:tty:62:23)
at file:///mnt/c/Users/Roy/AARK/Projects/js/t-console/$deno$eval:1:128
Is there any thought toward adding back in the lost capability and/or compatibility?
Adding functionality to FsFile might be a way forward and could also be a step towards correcting the loss of setRaw() functionality that I've reported last year in https://github.com/denoland/deno/issues/18175.