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>
This commit is contained in:
Jeremiah Senkpiel 2016-07-14 12:24:10 +02:00 коммит произвёл Anna Henningsen
Родитель 4878e1c0e5
Коммит ab3306ad51
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: D8B9F5AEAE84E4CF
4 изменённых файлов: 47 добавлений и 19 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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`:

Просмотреть файл

@ -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

Просмотреть файл

@ -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);