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>
v6.x
Jeremiah Senkpiel 9 years ago
committed by cjihrig
parent
commit
2f20910e24
  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. 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 [Buffer]: buffer.html#buffer_buffer
[debugger]: debugger.html [debugger]: debugger.html
[REPL]: repl.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 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 are sometimes *non-blocking* and may occur over multiple ticks of the Node.js
event loop. event loop. Calling `process.exit()`, however, forces the process to exit
Calling `process.exit()`, however, forces the process to exit *before* those *before* those additional writes to `stdout` can be performed.
additional writes to `stdout` can be performed.
Rather than calling `process.exit()` directly, the code *should* set the Rather than calling `process.exit()` directly, the code *should* set the
`process.exitCode` and allow the process to exit naturally by avoiding `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 The `process.stderr` property returns a [Writable][] stream equivalent to or
associated with `stderr` (fd `2`). associated with `stderr` (fd `2`).
`process.stderr` and `process.stdout` are unlike other streams in Node.js in Note: `process.stderr` and `process.stdout` differ from other Node.js streams
that they cannot be closed (calling [`end()`][] will throw an Error), they never in several ways:
emit the [`'finish'`][] event, and writes can block when output is redirected to 1. They cannot be closed ([`end()`][] will throw).
a file (although disks are fast and operating systems normally employ write-back 2. They never emit the [`'finish'`][] event.
caching so it should be a very rare occurrence indeed.) 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 check if Node.js is being run in a TTY context, read the `isTTY` property
to TTYs (terminals) on OS X as a workaround for the OS's very small, 1kb on `process.stderr`, `process.stdout`, or `process.stdin`:
buffer size. This is to prevent interleaving between `stdout` and `stderr`.
## process.stdin ## process.stdin
@ -1504,11 +1508,17 @@ console.log = (msg) => {
}; };
``` ```
`process.stderr` and `process.stdout` are unlike other streams in Node.js in Note: `process.stderr` and `process.stdout` differ from other Node.js streams
that they cannot be closed (calling [`end()`][] will throw an Error), they never in several ways:
emit the [`'finish'`][] event and that writes can block when output is 1. They cannot be closed ([`end()`][] will throw).
redirected to a file (although disks are fast and operating systems normally 2. They never emit the [`'finish'`][] event.
employ write-back caching so it should be a very rare occurrence indeed.) 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 To check if Node.js is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`: 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 is ~/.node_repl_history, which is overridden by this variable. Setting the
value to an empty string ("" or " ") disables persistent REPL history. 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 .SH RESOURCES AND DOCUMENTATION

4
lib/tty.js

@ -48,12 +48,12 @@ function WriteStream(fd) {
writable: true 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 // 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, // 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). // 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 // 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 winSize = [];
var err = this._handle.getWindowSize(winSize); var err = this._handle.getWindowSize(winSize);

Loading…
Cancel
Save