Permalink
Browse files

tty: set the handle to blocking mode

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #7743
PR-URL: #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>
  • Loading branch information...
Fishrock123 authored and addaleax committed Jul 14, 2016
1 parent 4878e1c commit ab3306ad51d8136014aa0fa9278b57bb77105320
Showing with 47 additions and 19 deletions.
  1. +11 −0 doc/api/cli.md
  2. +27 −17 doc/api/process.md
  3. +7 −0 doc/node.1
  4. +2 −2 lib/tty.js
View
@@ -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
View
@@ -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`:
View
@@ -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
View
@@ -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);

0 comments on commit ab3306a

Please sign in to comment.