Browse Source

tty: set the handle to blocking mode

Refs: https://github.com/nodejs/node/pull/1771
Refs: https://github.com/nodejs/node/issues/6456
Refs: https://github.com/nodejs/node/pull/6773
Refs: https://github.com/nodejs/node/issues/7743
PR-URL: https://github.com/nodejs/node/pull/6816
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Michaël Zasso <mic.besace@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
v7.x
Jeremiah Senkpiel 9 years ago
committed by Anna Henningsen
parent
commit
ab3306ad51
No known key found for this signature in database GPG Key ID: D8B9F5AEAE84E4CF
  1. 11
      doc/api/cli.md
  2. 44
      doc/api/process.md
  3. 7
      doc/node.1
  4. 4
      lib/tty.js

11
doc/api/cli.md

@ -288,6 +288,17 @@ Path to the file used to store the persistent REPL history. The default path is
to an empty string (`""` or `" "`) disables persistent REPL history.
### `NODE_TTY_UNSAFE_ASYNC=1`
<!-- YAML
added: REPLACEME
-->
When set to `1`, writes to `stdout` and `stderr` will be non-blocking and
asynchronous when outputting to a TTY on platforms which support async stdio.
Setting this will void any guarantee that stdio will not be interleaved or
dropped at program exit. **Use of this mode is not recommended.**
[Buffer]: buffer.html#buffer_buffer
[debugger]: debugger.html
[REPL]: repl.html

44
doc/api/process.md

@ -880,10 +880,9 @@ if (someConditionNotMet()) {
```
The reason this is problematic is because writes to `process.stdout` in Node.js
are usually *non-blocking* and may occur over multiple ticks of the Node.js
event loop.
Calling `process.exit()`, however, forces the process to exit *before* those
additional writes to `stdout` can be performed.
are sometimes *non-blocking* and may occur over multiple ticks of the Node.js
event loop. Calling `process.exit()`, however, forces the process to exit
*before* those additional writes to `stdout` can be performed.
Rather than calling `process.exit()` directly, the code *should* set the
`process.exitCode` and allow the process to exit naturally by avoiding
@ -1451,15 +1450,20 @@ Android)
The `process.stderr` property returns a [Writable][] stream equivalent to or
associated with `stderr` (fd `2`).
`process.stderr` and `process.stdout` are unlike other streams in Node.js in
that they cannot be closed (calling [`end()`][] will throw an Error), they never
emit the [`'finish'`][] event, and writes can block when output is redirected to
a file (although disks are fast and operating systems normally employ write-back
caching so it should be a very rare occurrence indeed.)
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
in several ways:
1. They cannot be closed ([`end()`][] will throw).
2. They never emit the [`'finish'`][] event.
3. Writes _can_ block when output is redirected to a file.
- Note that disks are fast and operating systems normally employ write-back
caching so this is very uncommon.
4. Writes on UNIX __will__ block by default if output is going to a TTY
(a terminal).
5. Windows functionality differs. Writes block except when output is going to a
TTY.
Additionally, `process.stderr` and `process.stdout` are blocking when outputting
to TTYs (terminals) on OS X as a workaround for the OS's very small, 1kb
buffer size. This is to prevent interleaving between `stdout` and `stderr`.
To check if Node.js is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`:
## process.stdin
@ -1504,11 +1508,17 @@ console.log = (msg) => {
};
```
`process.stderr` and `process.stdout` are unlike other streams in Node.js in
that they cannot be closed (calling [`end()`][] will throw an Error), they never
emit the [`'finish'`][] event and that writes can block when output is
redirected to a file (although disks are fast and operating systems normally
employ write-back caching so it should be a very rare occurrence indeed.)
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
in several ways:
1. They cannot be closed ([`end()`][] will throw).
2. They never emit the [`'finish'`][] event.
3. Writes _can_ block when output is redirected to a file.
- Note that disks are fast and operating systems normally employ write-back
caching so this is very uncommon.
4. Writes on UNIX __will__ block by default if output is going to a TTY
(a terminal).
5. Windows functionality differs. Writes block except when output is going to a
TTY.
To check if Node.js is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`:

7
doc/node.1

@ -194,6 +194,13 @@ Path to the file used to store the persistent REPL history. The default path
is ~/.node_repl_history, which is overridden by this variable. Setting the
value to an empty string ("" or " ") disables persistent REPL history.
.TP
.BR NODE_TTY_UNSAFE_ASYNC=1
When set to 1, writes to stdout and stderr will be non-blocking and asynchronous
when outputting to a TTY on platforms which support async stdio.
Setting this will void any guarantee that stdio will not be interleaved or
dropped at program exit. \fBAvoid use.\fR
.SH RESOURCES AND DOCUMENTATION

4
lib/tty.js

@ -48,12 +48,12 @@ function WriteStream(fd) {
writable: true
});
// Prevents interleaved stdout/stderr output in OS X terminals.
// Prevents interleaved or dropped stdout/stderr output for terminals.
// As noted in the following reference, local TTYs tend to be quite fast and
// this behaviour has become expected due historical functionality on OS X,
// even though it was originally intended to change in v1.0.2 (Libuv 1.2.1).
// Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671
if (process.platform === 'darwin') this._handle.setBlocking(true);
this._handle.setBlocking(process.env.NODE_TTY_UNSAFE_ASYNC !== '1');
var winSize = [];
var err = this._handle.getWindowSize(winSize);

Loading…
Cancel
Save